blob: 13c0be13a0623854029388681327bf5152f1699e [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
Harald Welte5ac31492018-02-15 20:39:13 +010034import from GSUP_Types all;
Pau Espin Pedrol8f1403a2024-01-18 20:08:43 +010035import from GSUP_Templates all;
36import from GSUP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010037import from IPA_Emulation all;
38
Harald Welte26fbb6e2019-04-14 17:32:46 +020039import from RAN_Adapter all;
40import from RAN_Emulation all;
41import from RANAP_Templates all;
42import from RANAP_PDU_Descriptions all;
43import from RANAP_IEs all;
44
Harald Welteeded9ad2018-02-17 20:57:34 +010045import from GTP_Emulation all;
46import from GTP_Templates all;
47import from GTP_CodecPort all;
48import from GTPC_Types all;
49import from GTPU_Types all;
50
Harald Weltea2526a82018-02-18 19:03:36 +010051import from LLC_Types all;
52import from LLC_Templates all;
53
54import from SNDCP_Types all;
55
Harald Weltebd194722018-02-16 22:11:08 +010056import from TELNETasp_PortType all;
57import from Osmocom_VTY_Functions all;
58
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020059import from MobileL3_MM_Types all;
60
Harald Welteeded9ad2018-02-17 20:57:34 +010061
Harald Welte5ac31492018-02-15 20:39:13 +010062modulepar {
63 /* IP/port on which we run our internal GSUP/HLR emulation */
64 charstring mp_hlr_ip := "127.0.0.1";
65 integer mp_hlr_port := 4222;
Pau Espin Pedrol7bac69f2021-05-04 15:53:06 +020066 charstring mp_ggsn_ip := "127.0.0.103";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020067 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +020068 charstring mp_sgsn_gtp_ip := "127.0.0.10";
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,
Harald Weltebe7afce2021-01-17 22:04:36 +010083 remote_ip := "127.0.0.1",
84 data_weight := 1,
85 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010086 }
87 },
88 nsvci := 97
89 }
90 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020091 },
92 {
Harald Welte5e514fa2018-07-05 00:01:45 +020093 nsei := 97,
94 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010095 handle_sns := false,
96 nsvc := {
97 {
98 provider := {
99 ip := {
100 address_family := AF_INET,
101 local_udp_port := 21011,
102 local_ip := "127.0.0.1",
103 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100104 remote_ip := "127.0.0.1",
105 data_weight := 1,
106 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100107 }
108 },
109 nsvci := 98
110 }
111 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200112 },
113 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200114 nsei := 98,
115 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100116 handle_sns := false,
117 nsvc := {
118 {
119 provider := {
120 ip := {
121 address_family := AF_INET,
122 local_udp_port := 21012,
123 local_ip := "127.0.0.1",
124 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100125 remote_ip := "127.0.0.1",
126 data_weight := 1,
127 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100128 }
129 },
130 nsvci := 99
131 }
132 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200133 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200134 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200135
136 RAN_Configurations mp_ranap_cfg := {
137 {
138 transport := RANAP_TRANSPORT_IuCS,
139 sccp_service_type := "mtp3_itu",
140 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
141 own_pc := 195,
142 own_ssn := 142,
143 peer_pc := 188, /* 0.23.4 */
144 peer_ssn := 142,
145 sio := '83'O,
146 rctx := 2
147 }
148 }
Harald Welte5ac31492018-02-15 20:39:13 +0100149};
150
Harald Welte5339b2e2020-10-04 22:52:56 +0200151const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100152type record GbInstance {
153 NS_CT vc_NS,
154 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200155 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100156 BssgpConfig cfg
157};
Harald Welte96a33b02018-02-04 10:36:22 +0100158
Harald Welte2fa771f2019-05-02 20:13:53 +0200159const integer NUM_GB := 3;
160type record length(NUM_GB) of GbInstance GbInstances;
161type record length(NUM_GB) of NSConfiguration NSConfigurations;
162type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200163
Harald Welte26fbb6e2019-04-14 17:32:46 +0200164const integer NUM_RNC := 1;
165type record of RAN_Configuration RAN_Configurations;
166
Harald Welte96a33b02018-02-04 10:36:22 +0100167type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200168 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200169 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200170 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100171
Harald Welte5ac31492018-02-15 20:39:13 +0100172 var GSUP_Emulation_CT vc_GSUP;
173 var IPA_Emulation_CT vc_GSUP_IPA;
174 /* only to get events from IPA underneath GSUP */
175 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100176
Harald Welte5339b2e2020-10-04 22:52:56 +0200177 /* only needed at start to get the per-BVC references */
178 port BSSGP_CT_PROC_PT PROC;
179
Philipp Maier7df55e02020-12-14 23:46:04 +0100180 /* used by RIM related test */
181 port BSSGP_PT RIM[NUM_GB];
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +0200182 port GTPEM_PT GTPC;
Philipp Maier7df55e02020-12-14 23:46:04 +0100183
Harald Welteeded9ad2018-02-17 20:57:34 +0100184 var GTP_Emulation_CT vc_GTP;
185
Harald Weltebd194722018-02-16 22:11:08 +0100186 port TELNETasp_PT SGSNVTY;
187
Harald Welte96a33b02018-02-04 10:36:22 +0100188 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200189 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100190};
191
Harald Welte26fbb6e2019-04-14 17:32:46 +0200192type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100193 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100194 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200195 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100196}
197
198type record SGSN_ConnHdlrNetworkPars {
199 boolean expect_ptmsi,
200 boolean expect_auth,
201 boolean expect_ciph
202};
203
204type record BSSGP_ConnHdlrPars {
205 /* IMEI of the simulated ME */
206 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200207 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100208 hexstring imsi,
209 /* MSISDN of the simulated MS (probably unused) */
210 hexstring msisdn,
211 /* P-TMSI allocated to the simulated MS */
212 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100213 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100214 /* TLLI of the simulated MS */
215 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100216 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100217 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200218 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200219 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
220 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100221 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100222 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200223 float t_guard,
224 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200225 SCCP_PAR_Address sccp_addr_local optional,
226 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100227};
228
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +0200229/* Passed in RAN-INFO message from emulated neighbor using RIM */
230const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
231const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
232const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
233const octetstring si_default := si1_default & si3_default & si13_default;
234
Alexander Couzens89508702018-07-31 04:16:10 +0200235private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200236 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200237 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
238
239 var RoutingAreaIdentificationV ret := {
240 mccDigit1 := mcc_mnc[0],
241 mccDigit2 := mcc_mnc[1],
242 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200243 mncDigit3 := mcc_mnc[3],
244 mncDigit1 := mcc_mnc[4],
245 mncDigit2 := mcc_mnc[5],
Pau Espin Pedroldeaaa902021-02-12 18:41:04 +0100246 lac := int2oct(cell_id.ra_id.lai.lac, 2),
247 rac := int2oct(cell_id.ra_id.rac, 1)
Alexander Couzens89508702018-07-31 04:16:10 +0200248 }
249 return ret;
250};
251
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +0100252private function f_BssgpCellId_to_GTP_CellId(in BssgpCellId cell_id) return GTP_CellId
253{
254 template (value) GTP_CellId ret := ts_GTP_CellId(cell_id.ra_id, cell_id.cell_id);
255 return valueof(ret);
256}
257
Alexander Couzens51114d12018-07-31 18:41:56 +0200258private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Pau Espin Pedrol494e8b32022-02-22 16:46:23 +0100259 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset)) alive;
260 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset)) alive;
Harald Welte5ac31492018-02-15 20:39:13 +0100261 /* connect lower end of BSSGP emulation with NS upper port */
262 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100263
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200264 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200265 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
266 /* resolve the per-BVC component references */
267 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
268 connect(self:PROC, gb.vc_BSSGP:PROC);
269 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
270 disconnect(self:PROC, gb.vc_BSSGP:PROC);
271 }
Philipp Maier7df55e02020-12-14 23:46:04 +0100272 /* connect RIM related port */
273 connect(gb.vc_BSSGP:RIM, self:RIM[offset]);
Harald Welte5ac31492018-02-15 20:39:13 +0100274}
275
276private function f_init_gsup(charstring id) runs on test_CT {
277 id := id & "-GSUP";
278 var GsupOps ops := {
279 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
280 };
281
282 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
283 vc_GSUP := GSUP_Emulation_CT.create(id);
284
285 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
286 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
287 /* we use this hack to get events like ASP_IPA_EVENT_UP */
288 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
289
290 vc_GSUP.start(GSUP_Emulation.main(ops, id));
291 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
292
293 /* wait for incoming connection to GSUP port before proceeding */
294 timer T := 10.0;
295 T.start;
296 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700297 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100298 [] T.timeout {
299 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200300 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100301 }
302 }
303}
304
Harald Welteeded9ad2018-02-17 20:57:34 +0100305private function f_init_gtp(charstring id) runs on test_CT {
306 id := id & "-GTP";
307
308 var GtpEmulationCfg gtp_cfg := {
309 gtpc_bind_ip := mp_ggsn_ip,
310 gtpc_bind_port := GTP1C_PORT,
311 gtpu_bind_ip := mp_ggsn_ip,
312 gtpu_bind_port := GTP1U_PORT,
313 sgsn_role := false
314 };
315
316 vc_GTP := GTP_Emulation_CT.create(id);
317 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
318}
319
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200320friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100321 map(self:SGSNVTY, system:SGSNVTY);
322 f_vty_set_prompts(SGSNVTY);
323 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200324 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100325 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
326}
327
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200328private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
329 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200330 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200331 } else {
332 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
333 }
334}
335
Harald Weltebd194722018-02-16 22:11:08 +0100336
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200337/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
338function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200339 var integer i;
340
Harald Welte96a33b02018-02-04 10:36:22 +0100341 if (g_initialized == true) {
342 return;
343 }
344 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100345 g_gb[0].cfg := {
346 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200347 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200348 bvc := {
349 {
350 bvci := 196,
351 cell_id := {
352 ra_id := {
353 lai := {
354 mcc_mnc := mcc_mnc,
355 lac := 13135
356 },
357 rac := 0
358 },
359 cell_id := 20960
360 },
Harald Welte4d112c92020-11-12 19:48:31 +0100361 depth := BSSGP_DECODE_DEPTH_L3,
362 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200363 }
364 }
Harald Welte5ac31492018-02-15 20:39:13 +0100365 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200366 g_gb[1].cfg := {
367 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200368 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200369 bvc := {
370 {
371 bvci := 210,
372 cell_id := {
373 ra_id := {
374 lai := {
375 mcc_mnc := mcc_mnc,
376 lac := 13200
377 },
378 rac := 0
379 },
380 cell_id := 20961
381 },
Harald Welte4d112c92020-11-12 19:48:31 +0100382 depth := BSSGP_DECODE_DEPTH_L3,
383 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200384 }
385 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200386 };
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100387 g_gb[2].cfg := { /* [2] configured to have same RAC as [1] */
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200388 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200389 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200390 bvc := {
391 {
392 bvci := 220,
393 cell_id := {
394 ra_id := {
395 lai := {
396 mcc_mnc := mcc_mnc,
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100397 lac := 13200
Harald Welte5339b2e2020-10-04 22:52:56 +0200398 },
399 rac := 0
400 },
401 cell_id := 20962
402 },
Harald Welte4d112c92020-11-12 19:48:31 +0100403 depth := BSSGP_DECODE_DEPTH_L3,
404 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200405 }
406 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200407 };
Harald Welte96a33b02018-02-04 10:36:22 +0100408
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200409 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200410 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
411 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
412 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200413
Alexander Couzens1552e792019-07-23 20:38:39 +0200414 if (g_ranap_enable) {
415 for (i := 0; i < NUM_RNC; i := i+1) {
416 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
417 f_ran_adapter_start(g_ranap[i]);
418 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200419 }
Harald Welte5ac31492018-02-15 20:39:13 +0100420 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100421 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200422 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100423}
Harald Welte96a33b02018-02-04 10:36:22 +0100424
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200425function f_cleanup() runs on test_CT {
426 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200427 if (g_ranap_enable) {
428 for (i := 0; i < NUM_RNC; i := i+1) {
429 f_ran_adapter_cleanup(g_ranap[i]);
430 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200431 }
432 self.stop;
433}
434
Harald Welte26fbb6e2019-04-14 17:32:46 +0200435private function RncUnitdataCallback(RANAP_PDU ranap)
436runs on RAN_Emulation_CT return template RANAP_PDU {
437 var template RANAP_PDU resp := omit;
438
439 log ("RANAP_RncUnitDataCallback");
440 /* answer all RESET with RESET ACK */
441 if (match(ranap, tr_RANAP_Reset)) {
442 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
443 var CN_DomainIndicator dom;
444 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
445 resp := ts_RANAP_ResetAck(dom);
446 }
447 return resp;
448}
449
450const RanOps RNC_RanOps := {
451 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
452 ranap_unitdata_cb := refers(RncUnitdataCallback),
453 ps_domain := true,
454 decode_dtap := true,
455 role_ms := true,
456 protocol := RAN_PROTOCOL_RANAP,
457 transport := RANAP_TRANSPORT_IuCS,
458 use_osmux := false,
Eric Wild6e511ce2022-04-02 21:35:56 +0200459 bssap_reset_retries := 1,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200460 sccp_addr_local := omit,
461 sccp_addr_peer := omit
462};
463
Harald Welte5ac31492018-02-15 20:39:13 +0100464type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
465
466/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200467function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100468 float t_guard := 30.0, boolean expect_ciph := false)
Harald Welte5ac31492018-02-15 20:39:13 +0100469runs on test_CT return BSSGP_ConnHdlr {
470 var BSSGP_ConnHdlr vc_conn;
471 var SGSN_ConnHdlrNetworkPars net_pars := {
472 expect_ptmsi := true,
473 expect_auth := true,
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100474 expect_ciph := expect_ciph
Harald Welte5ac31492018-02-15 20:39:13 +0100475 };
476 var BSSGP_ConnHdlrPars pars := {
477 imei := f_gen_imei(imsi_suffix),
478 imsi := f_gen_imsi(imsi_suffix),
479 msisdn := f_gen_msisdn(imsi_suffix),
480 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100481 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100482 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100483 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100484 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200485 bssgp_cell_id := {
486 gb[0].cfg.bvc[0].cell_id,
487 gb[1].cfg.bvc[0].cell_id,
488 gb[2].cfg.bvc[0].cell_id
489 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200490 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100491 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100492 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200493 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200494 sccp_addr_local := omit,
495 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100496 };
497
Alexander Couzens1552e792019-07-23 20:38:39 +0200498 if (g_ranap_enable) {
499 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
500 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
501 }
502
Harald Welte5ac31492018-02-15 20:39:13 +0100503 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200504
505 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
506 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
507 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100508 connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200509
510 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
511 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
512 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100513 connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200514
515 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
516 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
517 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100518 connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL);
Harald Welte5ac31492018-02-15 20:39:13 +0100519
Harald Welte26fbb6e2019-04-14 17:32:46 +0200520 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200521 if (g_ranap_enable) {
522 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
523 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
524 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200525
Harald Welte5ac31492018-02-15 20:39:13 +0100526 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
527 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
528
Harald Welteeded9ad2018-02-17 20:57:34 +0100529 connect(vc_conn:GTP, vc_GTP:CLIENT);
530 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
531
Harald Welte5ac31492018-02-15 20:39:13 +0100532 vc_conn.start(f_handler_init(fn, id, pars));
533 return vc_conn;
534}
535
Harald Welte62e29582018-02-16 21:17:11 +0100536private altstep as_Tguard() runs on BSSGP_ConnHdlr {
537 [] g_Tguard.timeout {
538 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200539 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100540 }
541}
542
Harald Welte5ac31492018-02-15 20:39:13 +0100543/* first function called in every ConnHdlr */
544private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
545runs on BSSGP_ConnHdlr {
546 /* do some common stuff like setting up g_pars */
547 g_pars := pars;
548
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200549 llc := f_llc_create(false);
550
Harald Welte5ac31492018-02-15 20:39:13 +0100551 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200552 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100553 /* tell GSUP dispatcher to send this IMSI to us */
554 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100555 /* tell GTP dispatcher to send this IMSI to us */
556 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100557
Harald Welte62e29582018-02-16 21:17:11 +0100558 g_Tguard.start(pars.t_guard);
559 activate(as_Tguard());
560
Harald Welte5ac31492018-02-15 20:39:13 +0100561 /* call the user-supplied test case function */
562 fn.apply(id);
563 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100564}
565
566/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100567 * Detach without Attach
568 * SM procedures without attach / RAU
569 * ATTACH / RAU
570 ** with / without authentication
571 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100572 * re-transmissions of LLC frames
573 * PDP Context activation
574 ** with different GGSN config in SGSN VTY
575 ** with different PDP context type (v4/v6/v46)
576 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100577 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100578 */
579
580testcase TC_wait_ns_up() runs on test_CT {
581 f_init();
582 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200583 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100584}
585
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200586friend function is_gb(integer ran_index) return boolean {
587 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200588}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200589friend function is_iu(integer ran_index) return boolean {
590 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200591}
592
Alexander Couzens0507ec32019-09-15 22:41:22 +0200593function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200594 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200595 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 +0200596}
597
Alexander Couzens0507ec32019-09-15 22:41:22 +0200598private 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 +0200599 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
600 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
601 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200602 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200603}
604
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200605/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
606function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
607 log("Sending InitialUE: ", l3_mo);
608 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
609 var RANAP_PDU ranap;
610 var LAI lai := {
611 pLMNidentity := '62F224'O,
612 lAC := '1234'O,
613 iE_Extensions := omit
614 };
615 var SAI sai := {
616 pLMNidentity := lai.pLMNidentity,
617 lAC := lai.lAC,
618 sAC := '0000'O, /* FIXME */
619 iE_Extensions := omit
620 };
621 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
622 var GlobalRNC_ID grnc_id := {
623 pLMNidentity := lai.pLMNidentity,
624 rNC_ID := 2342 /* FIXME */
625 };
626
627 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
628 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
629 alt {
630 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
631 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
632 setverdict(fail, "DISC.ind from SCCP");
633 mtc.stop;
634 }
635 }
636}
637
638/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200639function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
640 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200641 if (g_pars.rnc_send_initial_ue) {
642 g_pars.rnc_send_initial_ue := false;
643 f_send_l3_initial_ue(l3_mo);
644 } else {
645 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
646 }
647 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200648 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200649 }
650}
651
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200652altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700653 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200654 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100655 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200656 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100657 repeat;
658 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200659 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200660 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200661 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200662 repeat;
663 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200664 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100665 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200666 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200667 repeat;
668 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200669 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200670 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200671 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100672 repeat;
673 }
674}
Harald Welte96a33b02018-02-04 10:36:22 +0100675
Harald Welteca362462019-05-02 20:11:21 +0200676/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200677function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200678runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200679 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200680 var PDU_L3_SGSN_MS l3_mt;
681 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200682 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
683 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200684 l3_mt := mt.dtap;
685 }
Harald Welteca362462019-05-02 20:11:21 +0200686 }
687 return l3_mt;
688}
689
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100690/* (copied from msc/BSC_ConnectionHandler.ttcn) */
691private altstep as_ciph_utran() runs on BSSGP_ConnHdlr
692{
693 [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(uia_algs := ?,
694 uia_key := oct2bit(g_pars.vec.ik),
695 key_sts := ?,
696 uea_algs := ?,
697 uea_key := oct2bit(g_pars.vec.ck))) {
698 var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1*/
699 var EncryptionAlgorithm uea_chosen := 1; /*standard_UMTS_encryption_algorith_UEA1*/
700 BSSAP.send(ts_RANAP_SecurityModeCompleteEnc(uia_chosen, uea_chosen));
701 }
702 [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(?,?,?,?,?)) {
703 setverdict(fail, "Invalid SecurityModeCommand (ciphering case)");
704 mtc.stop;
705 }
706 [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?,
707 uia_key := oct2bit(g_pars.vec.ik),
708 key_sts := ?)) {
709 var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1;*/
710 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
711 }
712 [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(?,?,?)) {
713 setverdict(fail, "Invalid SecurityModeCommand (non-ciphering case)");
714 mtc.stop;
715 }
716}
717
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200718/* perform GMM authentication (if expected).
719 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
720 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200721function 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 +0100722 var PDU_L3_MS_SGSN l3_mo;
723 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200724 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100725 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200726 var GSUP_IE auth_tuple;
727 var template AuthenticationParameterAUTNTLV autn;
728
729 if (umts_aka_challenge) {
730 g_pars.vec := f_gen_auth_vec_3g();
731 autn := {
732 elementIdentifier := '28'O,
733 lengthIndicator := lengthof(g_pars.vec.autn),
734 autnValue := g_pars.vec.autn
735 };
736
737 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
738 g_pars.vec.sres,
739 g_pars.vec.kc,
740 g_pars.vec.ik,
741 g_pars.vec.ck,
742 g_pars.vec.autn,
743 g_pars.vec.res));
744 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
745 } else {
746 g_pars.vec := f_gen_auth_vec_2g();
747 autn := omit;
748 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
749 g_pars.vec.sres,
750 g_pars.vec.kc));
751 log("GSUP sends only 2G auth tuple", auth_tuple);
752 }
Harald Welteca362462019-05-02 20:11:21 +0200753
Harald Welte5ac31492018-02-15 20:39:13 +0100754 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
755 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200756
757 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
758 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200759 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100760 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +0700761 var template (value) PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200762
763 if (umts_aka_challenge and not force_gsm_sres) {
764 /* set UMTS response instead */
765 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
766 valueField := substr(g_pars.vec.res, 0, 4)
767 };
768 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
769 elementIdentifier := '21'O,
770 lengthIndicator := lengthof(g_pars.vec.res) - 4,
771 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
772 };
773 }
774
775 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100776 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
777 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
778 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
779 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
780 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200781 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200782
783 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200784 if (is_iu(ran_index)) {
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100785 as_ciph_utran();
786 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200787 }
Harald Welte76dee092018-02-16 22:12:59 +0100788 } else {
789 /* wait for identity procedure */
790 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100791 }
Harald Welte76dee092018-02-16 22:12:59 +0100792
Harald Welte5ac31492018-02-15 20:39:13 +0100793 deactivate(di);
794}
795
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200796function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100797 g_pars.p_tmsi := p_tmsi;
798 /* update TLLI */
799 g_pars.tlli_old := g_pars.tlli;
800 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100801 if (is_gb(ran_index)) {
802 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
803 }
Harald Weltef70997d2018-02-17 10:11:19 +0100804}
805
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100806function f_process_attach_accept(PDU_GMM_AttachAccept aa, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100807 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100808 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Harald Weltedd9fb842021-02-16 20:21:22 +0100809 /* we cannot use ran_index here, as it would overflow the cell_id object, since ran_idx > NUM_GB
810 * indicates an Iu RAN connection. All cells are expected to run the same MCC/MNC anyway... */
811 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100812 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100813 & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200814 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100815 }
Harald Welte04683d02018-02-16 22:43:45 +0100816 g_pars.ra := aa.routingAreaIdentification;
817 if (ispresent(aa.allocatedPTMSI)) {
818 if (not g_pars.net.expect_ptmsi) {
819 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200820 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100821 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100822 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
823 ran_index);
Harald Welte04683d02018-02-16 22:43:45 +0100824 }
825 if (ispresent(aa.msIdentity)) {
826 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200827 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100828 }
829 /* P-TMSI.sig */
830 if (ispresent(aa.ptmsiSignature)) {
831 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
832 }
833 /* updateTimer */
834 // aa.readyTimer
835 /* T3302, T3319, T3323, T3312_ext, T3324 */
836}
837
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200838function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100839 /* mandatory IE */
840 g_pars.ra := ra.routingAreaId;
841 if (ispresent(ra.allocatedPTMSI)) {
842 if (not g_pars.net.expect_ptmsi) {
843 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200844 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100845 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100846 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
847 ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100848 }
849 if (ispresent(ra.msIdentity)) {
850 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200851 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100852 }
853 /* P-TMSI.sig */
854 if (ispresent(ra.ptmsiSignature)) {
855 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
856 }
857 /* updateTimer */
858 // aa.readyTimer
859 /* T3302, T3319, T3323, T3312_ext, T3324 */
860}
861
862
Harald Welte5a4fa042018-02-16 20:59:21 +0100863function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
864 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
865}
866
Harald Welte23178c52018-02-17 09:36:33 +0100867/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700868private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100869 if (ispresent(g_pars.p_tmsi)) {
870 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
871 } else {
872 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
873 }
874}
875
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700876private altstep as_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
877 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
878 var GSUP_PDU gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
879 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
880 GSUP.send(gsup);
881 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
882 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
883 }
Harald Welte311ec272018-02-17 09:40:03 +0100884}
885
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100886friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0,
887 template (omit) RoutingAreaIdentificationV old_ra := omit) runs on BSSGP_ConnHdlr {
888 var RoutingAreaIdentificationV old_ra_val;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +0700889 var template (value) PDU_L3_MS_SGSN attach_req;
Harald Welteca362462019-05-02 20:11:21 +0200890 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100891
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100892 if (istemplatekind(old_ra, "omit")) {
893 old_ra_val := f_random_RAI();
894 } else {
895 old_ra_val := valueof(old_ra);
896 }
897
898 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra_val, false, false, omit, omit);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200899 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
900 * 3G auth vectors */
901 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
902 /* The thing is, if the solSACapability is 'omit', then the
903 * revisionLevelIndicatior is at the wrong place! */
904 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
905
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200906 f_send_l3(attach_req, ran_index);
907 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200908 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700909 as_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100910
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200911 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100912 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200913
Harald Welte04683d02018-02-16 22:43:45 +0100914 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200915 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200916
917 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200918 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200919 as_iu_release_compl_disc();
920 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200921
922 /* Race condition
923 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
924 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
925 * arrived before it. This results in a test case failure.
926 * Delay execution by 50 ms
927 */
928 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200929}
930
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200931friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
932 timer T := 5.0;
933 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100934 BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200935 T.start;
936 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100937 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200938 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
939 }
Harald Welte9b461a92020-12-10 23:41:14 +0100940 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200941 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
942 mtc.stop;
943 }
944 [] T.timeout {
945 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
946 mtc.stop;
947 }
948 }
949 return '00'O;
950}
951
952friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
953 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100954 BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200955 T.start;
956 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100957 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
958 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200959?)) {
960 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
961 mtc.stop;
962 }
963 [] T.timeout {
964 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
965 mtc.stop;
966 }
967 }
968}
969
970
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200971private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
972 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100973 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100974}
975
976testcase TC_attach() runs on test_CT {
977 var BSSGP_ConnHdlr vc_conn;
978 f_init();
979 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200980 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100981 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200982 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100983}
984
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100985testcase TC_attach_mnc3() runs on test_CT {
986 var BSSGP_ConnHdlr vc_conn;
987 f_init('023042'H);
988 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200989 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100990 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200991 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100992}
993
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200994private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
995 f_gmm_attach(true, false);
996 setverdict(pass);
997}
998testcase TC_attach_umts_aka_umts_res() runs on test_CT {
999 var BSSGP_ConnHdlr vc_conn;
1000 f_init();
1001 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001002 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001003 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001004 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001005}
1006
1007private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
1008 f_gmm_attach(true, true);
1009 setverdict(pass);
1010}
1011testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
1012 var BSSGP_ConnHdlr vc_conn;
1013 f_init();
1014 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001015 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001016 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001017 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001018}
1019
arehbein3ede9e32023-02-06 21:02:53 +01001020/* Let T3350 expire while the MS holds an active PDP context (OS#4221). Do this by
1021 * Establishing a PDP context and then resending an ATTACH REQUEST,
1022 * making sure that exactly five ATTACH ACCEPTS are sent */
1023private function f_TC_attach_timeout_after_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
1024 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1025 /* Vars needed for triggering T3350 timeouts */
1026 const integer ran_index := 0;
1027 /* See TS 24.008 Rel. 16 Sect. 4.7.3.1.6 c) */
1028 const integer gmm_attach_repeats := 5;
1029 /* See TS 24.008 Rel. 16 Table 11.4 */
1030 const float T3350 := 6.0;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07001031 var template (value) PDU_L3_MS_SGSN attach_req;
arehbein3ede9e32023-02-06 21:02:53 +01001032 timer t_receive_GMM_ATTACH_ACCEPT;
1033 var RoutingAreaIdentificationV rai := f_random_RAI();
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001034 timer T;
arehbein3ede9e32023-02-06 21:02:53 +01001035
1036 /* First establish PDP context */
1037 f_TC_attach(id);
1038 f_pdp_ctx_act(apars);
1039
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001040 /* Now, try another GPRS attach procedure. Note that osmo-sgsn does not require
1041 * authentication for the second GMM ATTACH REQUEST, so we expect GSUP UPDATE
1042 * LOCATION REQUEST and optionally a GMM IDENTITY REQUEST (IMEI). */
arehbein3ede9e32023-02-06 21:02:53 +01001043 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), rai, false, false, omit, omit);
1044 f_send_l3(attach_req, ran_index);
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001045
1046 T.start(1.0);
1047 alt {
1048 [] as_gmm_gsup_lu_isd();
1049 [] as_mm_identity(ran_index);
1050 [] as_xid(apars, ran_index);
1051 [] T.timeout {
1052 setverdict(fail, "Timeout waiting for GSUP UPDATE LOCATION REQUEST");
1053 return;
1054 }
1055 }
arehbein3ede9e32023-02-06 21:02:53 +01001056
1057 BSSGP[ran_index].clear;
1058 log("Trying to receive ", gmm_attach_repeats, " ATTACH ACCEPTs");
1059 for (var integer i := 1; i <= gmm_attach_repeats; i := i+1) {
1060 t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5);
1061 alt {
1062 [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) {
1063 t_receive_GMM_ATTACH_ACCEPT.stop;
1064 }
1065 [] t_receive_GMM_ATTACH_ACCEPT.timeout {
1066 setverdict(fail, "Timeout on receiving ", i, "th ATTACH ACCEPT")
1067 }
1068 }
1069 }
1070 log("Have received ", gmm_attach_repeats, " ATTACH ACCEPT messages");
1071 log("Make sure not more than ", gmm_attach_repeats, " ATTACH ACCEPT messages are sent");
1072 t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5);
1073 alt {
1074 [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) {
1075 setverdict(fail, "Received ", gmm_attach_repeats + 1, "th ATTACH ACCEPT")
1076 }
1077 [] t_receive_GMM_ATTACH_ACCEPT.timeout { }
1078 }
1079
1080 setverdict(pass);
1081}
1082
1083testcase TC_attach_timeout_after_pdp_act() runs on test_CT {
1084 var BSSGP_ConnHdlr vc_conn;
1085 f_init();
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001086 vc_conn := f_start_handler(refers(f_TC_attach_timeout_after_pdp_act),
1087 testcasename(), g_gb, 21, t_guard := 45.0);
1088 vc_conn.done;
arehbein3ede9e32023-02-06 21:02:53 +01001089 f_cleanup();
1090}
1091
Harald Welte5b7c8122018-02-16 21:48:17 +01001092/* MS never responds to ID REQ, expect ATTACH REJECT */
1093private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001094 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1095
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001096 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001097 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001098 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001099 /* don't send ID Response */
1100 repeat;
1101 }
Harald Welte955aa942019-05-03 01:29:29 +02001102 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001103 setverdict(pass);
1104 }
Harald Welte955aa942019-05-03 01:29:29 +02001105 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001106 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +02001107 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001108 }
1109 }
1110}
1111testcase TC_attach_auth_id_timeout() runs on test_CT {
1112 var BSSGP_ConnHdlr vc_conn;
1113 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001114 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 +01001115 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001116 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001117}
1118
1119/* HLR never responds to SAI REQ, expect ATTACH REJECT */
1120private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001121 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1122
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001123 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001124 alt {
1125 [] as_mm_identity();
1126 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1127 }
1128 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001129 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001130 setverdict(pass);
1131}
1132testcase TC_attach_auth_sai_timeout() runs on test_CT {
1133 var BSSGP_ConnHdlr vc_conn;
1134 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001135 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001136 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001137 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001138}
1139
Harald Weltefe253882018-02-17 09:25:00 +01001140/* HLR rejects SAI, expect ATTACH REJECT */
1141private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001142 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1143
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001144 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001145 alt {
1146 [] as_mm_identity();
1147 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1148 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1149 }
1150 }
Harald Welte955aa942019-05-03 01:29:29 +02001151 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001152 setverdict(pass);
1153}
1154testcase TC_attach_auth_sai_reject() runs on test_CT {
1155 var BSSGP_ConnHdlr vc_conn;
1156 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001157 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001158 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001159 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001160}
1161
Harald Welte5b7c8122018-02-16 21:48:17 +01001162/* HLR never responds to UL REQ, expect ATTACH REJECT */
1163private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001164 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001165 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1166
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001167 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001168 f_gmm_auth();
1169 /* Expect MSC to perform LU with HLR */
1170 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1171 /* Never follow-up with ISD_REQ or UL_RES */
1172 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001173 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001174 setverdict(pass);
1175 }
Harald Welte955aa942019-05-03 01:29:29 +02001176 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1177 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001178 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001179 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001180 }
1181 }
1182}
1183testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1184 var BSSGP_ConnHdlr vc_conn;
1185 f_init();
1186 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001187 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001188 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001189 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001190}
1191
Harald Welteb7c14e92018-02-17 09:29:16 +01001192/* HLR rejects UL REQ, expect ATTACH REJECT */
1193private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001194 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001195 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1196
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001197 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001198 f_gmm_auth();
1199 /* Expect MSC to perform LU with HLR */
1200 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1201 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1202 }
1203 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001204 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001205 setverdict(pass);
1206 }
Harald Welte955aa942019-05-03 01:29:29 +02001207 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1208 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001209 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001210 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001211 }
1212 }
1213}
1214testcase TC_attach_gsup_lu_reject() runs on test_CT {
1215 var BSSGP_ConnHdlr vc_conn;
1216 f_init();
1217 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001218 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001219 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001220 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001221}
1222
1223
Harald Welte3823e2e2018-02-16 21:53:48 +01001224/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1225private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001226 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001227 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1228
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001229 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001230 f_gmm_auth();
1231 /* Expect MSC to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07001232 as_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001233
Harald Welte955aa942019-05-03 01:29:29 +02001234 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1235 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001236 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001237 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001238 setverdict(pass);
1239}
Harald Welte3823e2e2018-02-16 21:53:48 +01001240testcase TC_attach_combined() runs on test_CT {
1241 var BSSGP_ConnHdlr vc_conn;
1242 f_init();
1243 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001244 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001245 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001246 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001247}
1248
Harald Welte76dee092018-02-16 22:12:59 +01001249/* Attempt of GPRS ATTACH in 'accept all' mode */
1250private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001251 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001252 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1253
1254 g_pars.net.expect_auth := false;
1255
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001256 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001257 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001258 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1259 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001260 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001261 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001262 setverdict(pass);
1263}
1264testcase TC_attach_accept_all() runs on test_CT {
1265 var BSSGP_ConnHdlr vc_conn;
1266 f_init();
1267 f_sleep(1.0);
1268 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001269 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001270 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001271 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001272}
Harald Welte5b7c8122018-02-16 21:48:17 +01001273
Harald Welteb2124b22018-02-16 22:26:56 +01001274/* Attempt of GPRS ATTACH in 'accept all' mode */
1275private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001276 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1277
1278 /* Simulate a foreign IMSI */
1279 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001280 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001281
1282 g_pars.net.expect_auth := false;
1283
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001284 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001285 alt {
1286 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001287 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001288 setverdict(pass);
1289 }
Harald Welte955aa942019-05-03 01:29:29 +02001290 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001291 setverdict(pass);
1292 }
Harald Welte955aa942019-05-03 01:29:29 +02001293 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001294 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001295 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001296 }
Harald Welteb2124b22018-02-16 22:26:56 +01001297 }
1298}
1299testcase TC_attach_closed() runs on test_CT {
1300 var BSSGP_ConnHdlr vc_conn;
1301 f_init();
1302 f_sleep(1.0);
1303 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1304 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001305 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001306 vc_conn.done;
1307 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001308 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001309 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001310 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001311}
1312
Harald Welte04683d02018-02-16 22:43:45 +01001313/* Routing Area Update from Unknown TLLI -> REJECT */
1314private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001315 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1316
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001317 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 +01001318 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001319 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001320 setverdict(pass);
1321 }
1322 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001323 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001324 }
1325}
1326testcase TC_rau_unknown() runs on test_CT {
1327 var BSSGP_ConnHdlr vc_conn;
1328 f_init();
1329 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001330 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001331 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001332 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001333}
1334
Harald Welte91636de2018-02-17 10:16:14 +01001335private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001336 /* first perform regular attach */
1337 f_TC_attach(id);
1338
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001339 f_routing_area_update(g_pars.ra);
1340
Harald Welte91636de2018-02-17 10:16:14 +01001341}
1342testcase TC_attach_rau() runs on test_CT {
1343 var BSSGP_ConnHdlr vc_conn;
1344 f_init();
1345 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001346 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001347 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001348 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001349}
Harald Welte04683d02018-02-16 22:43:45 +01001350
Harald Welte6abb9fe2018-02-17 15:24:48 +01001351/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001352function 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 +02001353 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001354 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001355 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001356 if (expect_purge) {
1357 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1358 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1359 }
1360 T.start;
1361 alt {
1362 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1363 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001364 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001365 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001366 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001367 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001368 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001369 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001370 /* TODO: check if any PDP contexts are deactivated on network side? */
1371 }
1372 [power_off] T.timeout {
1373 setverdict(pass);
1374 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001375 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001376 g_pars.ra := omit;
1377 setverdict(pass);
1378 /* TODO: check if any PDP contexts are deactivated on network side? */
1379 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001380 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001381 if (power_off) {
1382 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1383 } else {
1384 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1385 }
1386 mtc.stop;
1387 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001388 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001389 }
1390}
1391
1392/* IMSI DETACH (non-power-off) for unknown TLLI */
1393private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1394 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1395}
1396testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1397 var BSSGP_ConnHdlr vc_conn;
1398 f_init();
1399 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001400 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001401 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001402 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001403}
1404
1405/* IMSI DETACH (power-off) for unknown TLLI */
1406private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1407 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1408}
1409testcase TC_detach_unknown_poweroff() runs on test_CT {
1410 var BSSGP_ConnHdlr vc_conn;
1411 f_init();
1412 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001413 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001414 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001415 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001416}
1417
1418/* IMSI DETACH (non-power-off) for known TLLI */
1419private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1420 /* first perform regular attach */
1421 f_TC_attach(id);
1422
1423 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1424}
1425testcase TC_detach_nopoweroff() runs on test_CT {
1426 var BSSGP_ConnHdlr vc_conn;
1427 f_init();
1428 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001429 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001430 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001431 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001432}
1433
1434/* IMSI DETACH (power-off) for known TLLI */
1435private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1436 /* first perform regular attach */
1437 f_TC_attach(id);
1438
1439 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1440}
1441testcase TC_detach_poweroff() runs on test_CT {
1442 var BSSGP_ConnHdlr vc_conn;
1443 f_init();
1444 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001445 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001446 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001447 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001448}
1449
Harald Welteeded9ad2018-02-17 20:57:34 +01001450type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001451 BIT3 tid, /* L3 Transaction ID */
1452 BIT4 nsapi, /* SNDCP NSAPI */
1453 BIT4 sapi, /* LLC SAPI */
1454 QoSV qos, /* QoS parameters */
1455 PDPAddressV addr, /* IP address */
1456 octetstring apn optional, /* APN name */
1457 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1458 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001459 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001460 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001461
Harald Welte822f9102018-02-18 20:39:06 +01001462 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1463 OCT4 ggsn_tei_u, /* GGSN TEI User */
1464 octetstring ggsn_ip_c, /* GGSN IP Control */
1465 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001466 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001467
Harald Welte822f9102018-02-18 20:39:06 +01001468 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1469 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1470 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1471 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001472};
1473
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001474
1475private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1476 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1477 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1478 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1479 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1480 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1481 f_gtp_register_teid(apars.ggsn_tei_c);
1482 f_gtp_register_teid(apars.ggsn_tei_u);
1483}
1484
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001485function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001486runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001487 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1488 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001489 var template Recovery_gtpc recovery := omit;
1490
1491 if (send_recovery) {
1492 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1493 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001494
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001495 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 +02001496 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001497 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1498 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1499 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1500 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1501 apars.sgsn_tei_c, apars.gtp_resp_cause,
1502 apars.ggsn_tei_c, apars.ggsn_tei_u,
1503 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001504 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1505 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001506 }
1507 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001508 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001509 setverdict(pass);
1510 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001511 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001512 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001513 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001514 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001515 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001516 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001517 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001518 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001519 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001520 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1521 mtc.stop;
1522 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001523 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001524 setverdict(pass);
1525 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001526 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001527 }
1528}
1529
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001530function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001531runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001532 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1533 var Gtp1cUnitdata g_ud;
1534
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001535 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001536 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1537 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001538 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001539 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1540 }
1541 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001542 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001543 setverdict(pass);
1544 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001545 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001546 }
1547}
1548
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001549function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001550runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001551 var Gtp1cUnitdata g_ud;
1552 var integer seq_nr := 23;
1553 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1554
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001555 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001556 if (error_ind) {
1557 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1558 } else {
1559 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1560 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001561
1562 timer T := 5.0;
1563 T.start;
1564
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001565 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001566 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1567 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001568 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001569 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1570 repeat;
1571 }
1572 [] T.timeout {
1573 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1574 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001575 }
1576}
1577
Harald Welte6f203162018-02-18 22:04:55 +01001578
Harald Welteeded9ad2018-02-17 20:57:34 +01001579/* Table 10.5.156/3GPP TS 24.008 */
1580template (value) QoSV t_QosDefault := {
1581 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1582 delayClass := '100'B, /* best effort */
1583 spare1 := '00'B,
1584 precedenceClass := '010'B, /* normal */
1585 spare2 := '0'B,
1586 peakThroughput := '0000'B, /* subscribed */
1587 meanThroughput := '00000'B, /* subscribed */
1588 spare3 := '000'B,
1589 deliverErroneusSDU := omit,
1590 deliveryOrder := omit,
1591 trafficClass := omit,
1592 maxSDUSize := omit,
1593 maxBitrateUplink := omit,
1594 maxBitrateDownlink := omit,
1595 sduErrorRatio := omit,
1596 residualBER := omit,
1597 trafficHandlingPriority := omit,
1598 transferDelay := omit,
1599 guaranteedBitRateUplink := omit,
1600 guaranteedBitRateDownlink := omit,
1601 sourceStatisticsDescriptor := omit,
1602 signallingIndication := omit,
1603 spare4 := omit,
1604 maxBitrateDownlinkExt := omit,
1605 guaranteedBitRateDownlinkExt := omit,
1606 maxBitrateUplinkExt := omit,
1607 guaranteedBitRateUplinkExt := omit,
1608 maxBitrateDownlinkExt2 := omit,
1609 guaranteedBitRateDownlinkExt2 := omit,
1610 maxBitrateUplinkExt2 := omit,
1611 guaranteedBitRateUplinkExt2 := omit
1612}
1613
1614/* 10.5.6.4 / 3GPP TS 24.008 */
1615template (value) PDPAddressV t_AddrIPv4dyn := {
1616 pdpTypeOrg := '0001'B, /* IETF */
1617 spare := '0000'B,
1618 pdpTypeNum := '21'O, /* IPv4 */
1619 addressInfo := omit
1620}
1621template (value) PDPAddressV t_AddrIPv6dyn := {
1622 pdpTypeOrg := '0001'B, /* IETF */
1623 spare := '0000'B,
1624 pdpTypeNum := '53'O, /* IPv6 */
1625 addressInfo := omit
1626}
1627
Harald Welte37692d82018-02-18 15:21:34 +01001628template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001629 tid := '000'B,
1630 nsapi := '0101'B, /* < 5 are reserved */
1631 sapi := '0011'B, /* 3/5/9/11 */
1632 qos := t_QosDefault,
1633 addr := t_AddrIPv4dyn,
1634 apn := omit,
1635 pco := omit,
1636 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001637 gtp_resp_cause := int2oct(128, 1),
1638 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001639
1640 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001641 ggsn_tei_c := f_rnd_octstring(4),
1642 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001643 ggsn_ip_c := f_inet_addr(ggsn_ip),
1644 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001645 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001646
Harald Welteeded9ad2018-02-17 20:57:34 +01001647 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001648 sgsn_tei_u := omit,
1649 sgsn_ip_c := omit,
1650 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001651}
1652
Harald Welte37692d82018-02-18 15:21:34 +01001653template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1654 connId := 1,
1655 remName := f_inet_ntoa(ip),
1656 remPort := GTP1U_PORT
1657}
1658
1659template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1660 connId := 1,
1661 remName := f_inet_ntoa(ip),
1662 remPort := GTP1C_PORT
1663}
1664
1665private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1666 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1667 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1668}
1669
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001670private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1671 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001672 repeat;
1673 }
1674}
1675
1676template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1677 pDU_SN_UNITDATA := {
1678 nsapi := nsapi,
1679 moreBit := ?,
1680 snPduType := '1'B,
1681 firstSegmentIndicator := ?,
1682 spareBit := ?,
1683 pcomp := ?,
1684 dcomp := ?,
1685 npduNumber := ?,
1686 segmentNumber := ?,
1687 npduNumberContinued := ?,
1688 dataSegmentSnUnitdataPdu := payload
1689 }
1690}
1691
1692/* simple case: single segment, no compression */
1693template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1694 pDU_SN_UNITDATA := {
1695 nsapi := nsapi,
1696 moreBit := '0'B,
1697 snPduType := '1'B,
1698 firstSegmentIndicator := '1'B,
1699 spareBit := '0'B,
1700 pcomp := '0000'B,
1701 dcomp := '0000'B,
1702 npduNumber := '0000'B,
1703 segmentNumber := '0000'B,
1704 npduNumberContinued := '00'O,
1705 dataSegmentSnUnitdataPdu := payload
1706 }
1707}
1708
1709/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001710private 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 +02001711runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001712 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001713 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1714 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001715 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001716 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1717 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001718 [] as_xid(apars, ran_index);
1719 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001720 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1721 [expect_fwd] T.timeout {
1722 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1723 mtc.stop;
1724 }
1725 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1726 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1727 mtc.stop;
1728 }
1729 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001730 }
1731}
1732
Harald Welte64d6b512020-06-17 16:42:00 +02001733/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001734private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0, uint9_t n_u := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001735runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001736 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1737 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1738 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001739 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, n_u));
Harald Welte37692d82018-02-18 15:21:34 +01001740 /* Expect PDU via GTP from SGSN on simulated GGSN */
1741 alt {
1742 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1743 }
1744}
1745
Harald Welteeded9ad2018-02-17 20:57:34 +01001746private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001747 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001748
1749 /* first perform regular attach */
1750 f_TC_attach(id);
1751
1752 f_pdp_ctx_act(apars);
1753}
1754testcase TC_attach_pdp_act() runs on test_CT {
1755 var BSSGP_ConnHdlr vc_conn;
1756 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001757 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001758 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001759 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001760}
Harald Welteb2124b22018-02-16 22:26:56 +01001761
Harald Welte835b15f2018-02-18 14:39:11 +01001762/* PDP Context activation for not-attached subscriber; expect fail */
1763private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001764 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001765 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 +01001766 apars.apn, apars.pco));
1767 alt {
1768 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001769 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001770 setverdict(pass);
1771 }
1772 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1773 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001774 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001775 }
Harald Welte955aa942019-05-03 01:29:29 +02001776 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001777 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001778 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001779 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001780 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001781 }
1782}
1783testcase TC_pdp_act_unattached() runs on test_CT {
1784 var BSSGP_ConnHdlr vc_conn;
1785 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001786 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001787 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001788 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001789}
1790
Harald Welte37692d82018-02-18 15:21:34 +01001791/* ATTACH + PDP CTX ACT + user plane traffic */
1792private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1793 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1794
1795 /* first perform regular attach */
1796 f_TC_attach(id);
1797 /* then activate PDP context */
1798 f_pdp_ctx_act(apars);
1799 /* then transceive a downlink PDU */
1800 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1801 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1802}
1803testcase TC_attach_pdp_act_user() runs on test_CT {
1804 var BSSGP_ConnHdlr vc_conn;
1805 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001806 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001807 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001808 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001809}
1810
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001811/* ATTACH + PDP CTX ACT; reject from GGSN */
1812private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1813 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1814
1815 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1816 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1817
1818 /* first perform regular attach */
1819 f_TC_attach(id);
1820 /* then activate PDP context */
1821 f_pdp_ctx_act(apars);
1822}
1823testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1824 var BSSGP_ConnHdlr vc_conn;
1825 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001826 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001827 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001828 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001829}
Harald Welte835b15f2018-02-18 14:39:11 +01001830
Harald Welte6f203162018-02-18 22:04:55 +01001831/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1832private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1833 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1834
1835 /* first perform regular attach */
1836 f_TC_attach(id);
1837 /* then activate PDP context */
1838 f_pdp_ctx_act(apars);
1839 /* then transceive a downlink PDU */
1840 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1841 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1842
1843 f_pdp_ctx_deact_mo(apars, '00'O);
1844}
1845testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1846 var BSSGP_ConnHdlr vc_conn;
1847 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001848 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 +01001849 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001850 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001851}
1852
Harald Welte57b9b7f2018-02-18 22:28:13 +01001853/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1854private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1855 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1856
1857 /* first perform regular attach */
1858 f_TC_attach(id);
1859 /* then activate PDP context */
1860 f_pdp_ctx_act(apars);
1861 /* then transceive a downlink PDU */
1862 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1863 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1864
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001865 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001866}
1867testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1868 var BSSGP_ConnHdlr vc_conn;
1869 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001870 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 +01001871 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001872 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001873}
1874
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001875/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1876private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1877 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1878 var Gtp1cUnitdata g_ud;
1879 var integer i;
1880 var OCT1 cause_regular_deact := '24'O;
1881
1882 /* first perform regular attach + PDP context act */
1883 f_TC_attach(id);
1884 f_pdp_ctx_act(apars);
1885
1886 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1887 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1888
1889 for (i := 0; i < 2; i := i+1) {
1890 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1891 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1892 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1893 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1894 }
1895 }
1896
1897 alt {
1898 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1899 setverdict(pass);
1900 }
1901 [] as_xid(apars, 0);
1902 }
1903
1904 /* Make sure second DeactPdpAccept is sent: */
1905 timer T := 2.0;
1906 T.start;
1907 alt {
1908 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1909 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1910 }
1911 [] T.timeout {
1912 setverdict(pass);
1913 }
1914 }
1915
1916 setverdict(pass);
1917}
1918testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1919 var BSSGP_ConnHdlr vc_conn;
1920 f_init();
1921 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1922 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001923 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001924}
1925
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001926/* ATTACH + ATTACH (2nd) */
1927private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1928 g_pars.t_guard := 5.0;
1929
1930 /* first perform regular attach */
1931 f_TC_attach(id);
1932
1933 /* second to perform regular attach */
1934 f_TC_attach(id);
1935}
1936
1937
1938testcase TC_attach_second_attempt() runs on test_CT {
1939 var BSSGP_ConnHdlr vc_conn;
1940 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001941 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001942 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001943 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001944}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001945
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001946private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1947 var Gtp1cUnitdata g_ud;
1948 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1949 var integer seq_nr;
1950
1951 /* first perform regular attach */
1952 f_TC_attach(id);
1953 /* then activate PDP context */
1954 f_pdp_ctx_act(apars);
1955
1956 /* Wait to receive first echo request and send initial Restart counter */
1957 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1958 BSSGP[0].clear;
1959 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1960 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1961 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1962 }
1963
1964 /* At some point next echo request not answered will timeout and SGSN
1965 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1966 timer T := 3.0 * 6.0 + 16.0;
1967 T.start;
1968 alt {
1969 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1970 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1971 setverdict(pass);
1972 }
1973 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1974 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1975 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1976 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1977 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1978 repeat;
1979 }
1980 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1981 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1982 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1983 repeat;
1984 }
1985 [] T.timeout {
1986 setverdict(fail, "BSSGP DeactPdpReq not received");
1987 mtc.stop;
1988 }
1989 [] as_xid(apars);
1990 }
1991 T.stop
1992
1993 setverdict(pass);
1994}
1995/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1996testcase TC_attach_echo_timeout() runs on test_CT {
1997 var BSSGP_ConnHdlr vc_conn;
1998 g_use_echo := true;
1999 f_init();
2000 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
2001 vc_conn.done;
2002 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002003 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002004}
2005
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002006private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002007 var Gtp1cUnitdata g_ud;
2008 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2009
2010 /* first perform regular attach */
2011 f_TC_attach(id);
2012 /* Activate a pdp context against the GGSN */
2013 f_pdp_ctx_act(apars);
2014 /* Wait to receive first echo request and send initial Restart counter */
2015 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
2016 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
2017 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
2018 }
2019 /* Wait to receive second echo request and send incremented Restart
2020 counter. This will fake a restarted GGSN, and pdp ctx allocated
2021 should be released by SGSN */
2022 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
2023 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
2024 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
2025 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
2026 }
2027 var OCT1 cause_network_failure := int2oct(38, 1)
2028 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002029 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002030 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002031 setverdict(pass);
2032 }
2033 [] as_xid(apars);
2034 }
2035 setverdict(pass);
2036}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002037/* ATTACH + trigger Recovery procedure through EchoResp */
2038testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002039 var BSSGP_ConnHdlr vc_conn;
2040 g_use_echo := true
2041 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002042 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 +02002043 vc_conn.done;
2044 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002045 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002046}
2047
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002048private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
2049 var Gtp1cUnitdata g_ud;
2050 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2051 var integer seq_nr := 23;
2052 var GtpPeer peer;
2053 /* first perform regular attach */
2054 f_TC_attach(id);
2055
2056 /* Use this CTX ACT to send initial Restart counter to SGSN. */
2057 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
2058 apars.exp_rej_cause := '1a'O; /* insufficient resources */
2059 f_pdp_ctx_act(apars, true);
2060
2061 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
2062/* received. */
2063 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
2064
2065 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
2066 would be great to have an active pdp context here before triggering
2067 Recovery, and making sure the the DEACT request is sent by the SGSN.
2068 */
2069
2070 /* Activate a pdp context against the GGSN, send incremented Recovery
2071 IE. This should trigger the recovery path, but still this specific
2072 CTX activation should work. */
2073 apars.exp_rej_cause := omit; /* default value for tests */
2074 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
2075 f_pdp_ctx_act(apars, true);
2076
2077 setverdict(pass);
2078}
2079/* ATTACH + trigger Recovery procedure through CreatePdpResp */
2080testcase TC_attach_restart_ctr_create() runs on test_CT {
2081 var BSSGP_ConnHdlr vc_conn;
2082 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002083 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 +02002084 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002085 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002086}
2087
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002088/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
2089private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
2090 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2091 var integer seq_nr := 23;
2092 var GtpPeer peer;
2093 var integer i;
2094
2095 /* first perform regular attach */
2096 f_TC_attach(id);
2097 /* then activate PDP context */
2098 f_pdp_ctx_act(apars);
2099
Alexander Couzens0e510e62018-07-28 23:06:00 +02002100 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002101 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2102 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
2103
2104 for (i := 0; i < 5; i := i+1) {
2105 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002106 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002107 [] as_xid(apars);
2108 }
2109 }
2110
2111 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
2112
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002113 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002114 setverdict(pass);
2115}
2116testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
2117 var BSSGP_ConnHdlr vc_conn;
2118 f_init();
2119 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002120 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 +02002121 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002122 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002123}
2124
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002125/* ATTACH + PDP CTX ACT dropped + retrans */
2126private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2127 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2128 var Gtp1cUnitdata g_ud_first, g_ud_second;
2129 /* first perform regular attach */
2130 f_TC_attach(id);
2131
2132 /* then activate PDP context on the Gb side */
2133 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2134 apars.apn, apars.pco), 0);
2135
2136 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2137 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2138 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2139 if (g_ud_first != g_ud_second) {
2140 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2141 mtc.stop;
2142 }
2143 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2144 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2145 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2146 apars.sgsn_tei_c, apars.gtp_resp_cause,
2147 apars.ggsn_tei_c, apars.ggsn_tei_u,
2148 apars.nsapi,
2149 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2150 omit, omit));
2151 }
Harald Welte955aa942019-05-03 01:29:29 +02002152 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002153
2154 /* Now the same with Deact */
2155 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2156 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2157 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2158 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2159 if (g_ud_first != g_ud_second) {
2160 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2161 mtc.stop;
2162 }
2163 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2164 BSSGP[0].clear;
2165 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2166 }
2167 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002168 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002169 setverdict(pass);
2170 }
2171 [] as_xid(apars, 0);
2172 }
2173
2174 setverdict(pass);
2175}
2176testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2177 var BSSGP_ConnHdlr vc_conn;
2178 f_init();
2179 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2180 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002181 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002182}
2183
2184/* Test that SGSN GTP response retransmit queue works fine */
2185private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2186 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2187 var integer seq_nr := 23;
2188 var Gtp1cUnitdata g_ud_first, g_ud_second;
2189 var template Gtp1cUnitdata g_delete_req;
2190 /* first perform regular attach + PDP context act */
2191 f_TC_attach(id);
2192 f_pdp_ctx_act(apars);
2193
2194 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2195 BSSGP[0].clear;
2196 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2197 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2198 GTP.send(g_delete_req);
2199 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002200 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002201 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2202 }
2203 [] as_xid(apars, 0);
2204 }
2205 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2206 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2207 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2208 mtc.stop;
2209 }
2210 };
2211
2212 /* Send duplicate DeleteCtxReq */
2213 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2214 GTP.send(g_delete_req);
2215 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2216 if (g_ud_first != g_ud_second) {
2217 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2218 mtc.stop;
2219 }
2220 }
2221
2222 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2223 * is handled differently by SGSN (expect "non-existent" cause) */
2224 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2225 GTP.send(g_delete_req);
2226 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2227 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2228 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2229 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2230 mtc.stop;
2231 }
2232 }
2233
2234 setverdict(pass);
2235}
2236testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2237 var BSSGP_ConnHdlr vc_conn;
2238 f_init();
2239 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2240 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002241 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002242}
2243
Alexander Couzens5e307b42018-05-22 18:12:20 +02002244private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2245 /* MS: perform regular attach */
2246 f_TC_attach(id);
2247
2248 /* HLR: cancel the location request */
2249 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2250 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002251
2252 /* ensure no Detach Request got received */
2253 timer T := 5.0;
2254 T.start;
2255 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002256 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002257 T.stop;
2258 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002259 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002260 }
2261 [] T.timeout {
2262 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002263 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002264 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002265 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002266 repeat;
2267 }
2268 }
2269}
2270
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002271/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2272private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2273 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2274
2275 /* first perform regular attach */
2276 f_TC_attach(id);
2277 /* then activate PDP context */
2278 f_pdp_ctx_act(apars);
2279 /* then transceive a downlink PDU */
2280 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2281
2282 /* Send Error indication as response from upload PDU and expect deact towards MS */
2283 f_pdp_ctx_deact_mt(apars, true);
2284}
2285testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2286 var BSSGP_ConnHdlr vc_conn;
2287 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002288 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 +02002289 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002290 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002291}
2292
Alexander Couzens5e307b42018-05-22 18:12:20 +02002293testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2294 /* MS <-> SGSN: GMM Attach
2295 * HLR -> SGSN: Cancel Location Request
2296 * HLR <- SGSN: Cancel Location Ack
2297 */
2298 var BSSGP_ConnHdlr vc_conn;
2299 f_init();
2300 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002301 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002302 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002303 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002304}
2305
2306
Alexander Couzensc87967a2018-05-22 16:09:54 +02002307private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2308 /* MS: perform regular attach */
2309 f_TC_attach(id);
2310
2311 /* HLR: cancel the location request */
2312 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2313 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2314 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2315
2316 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002317 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002318 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002319
2320 setverdict(pass);
2321}
2322
2323testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2324 /* MS <-> SGSN: GMM Attach
2325 * HLR -> SGSN: Cancel Location Request
2326 * HLR <- SGSN: Cancel Location Ack
2327 * MS <- SGSN: Detach Request
2328 * SGSN-> MS: Detach Complete
2329 */
2330 var BSSGP_ConnHdlr vc_conn;
2331 f_init();
2332 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002333 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002334 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002335 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002336}
2337
2338
Alexander Couzens6c47f292018-05-22 17:09:49 +02002339private function f_hlr_location_cancel_request_unknown_subscriber(
2340 charstring id,
2341 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2342
2343 /* HLR: cancel the location request */
2344 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2345
2346 /* cause 2 = IMSI_UNKNOWN */
2347 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2348
2349 setverdict(pass);
2350}
2351
2352private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002353 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002354}
2355
2356testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2357 /* HLR -> SGSN: Cancel Location Request
2358 * HLR <- SGSN: Cancel Location Error
2359 */
2360
2361 var BSSGP_ConnHdlr vc_conn;
2362 f_init();
2363 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002364 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 +02002365 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002366 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002367}
2368
2369private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002370 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002371}
2372
2373testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2374 /* HLR -> SGSN: Cancel Location Request
2375 * HLR <- SGSN: Cancel Location Error
2376 */
2377
2378 var BSSGP_ConnHdlr vc_conn;
2379 f_init();
2380 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002381 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 +02002382 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002383 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002384}
2385
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002386private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2387 f_TC_attach(id);
2388 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2389}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002390
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002391testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2392 /* MS <-> SGSN: Attach
2393 * MS -> SGSN: Detach Req (Power off)
2394 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2395 */
2396 var BSSGP_ConnHdlr vc_conn;
2397 var integer id := 33;
2398 var charstring imsi := hex2str(f_gen_imsi(id));
2399
2400 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002401 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002402 vc_conn.done;
2403
2404 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002405 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002406}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002407
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002408/* Attempt an attach, but loose the Identification Request (IMEI) */
2409private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2410 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002411 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002412
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002413 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 +02002414
2415 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002416 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002417 /* break */
2418 }
Harald Welte955aa942019-05-03 01:29:29 +02002419 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002420 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002421 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002422 repeat;
2423 }
Harald Welte955aa942019-05-03 01:29:29 +02002424 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002425 /* ignore ID REQ IMEI */
2426 count_req := count_req + 1;
2427 repeat;
2428 }
2429 }
2430 if (count_req != 5) {
2431 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002432 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002433 }
2434 setverdict(pass);
2435}
2436
2437testcase TC_attach_no_imei_response() runs on test_CT {
2438 /* MS -> SGSN: Attach Request IMSI
2439 * MS <- SGSN: Identity Request IMSI (optional)
2440 * MS -> SGSN: Identity Response IMSI (optional)
2441 * MS <- SGSN: Identity Request IMEI
2442 * MS -x SGSN: no response
2443 * MS <- SGSN: re-send: Identity Request IMEI 4x
2444 * MS <- SGSN: Attach Reject
2445 */
2446 var BSSGP_ConnHdlr vc_conn;
2447 f_init();
2448 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002449 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 +02002450 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002451 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002452}
2453
Alexander Couzens53f20562018-06-12 16:24:12 +02002454/* Attempt an attach, but loose the Identification Request (IMSI) */
2455private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2456 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002457 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002458
2459 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2460 g_pars.p_tmsi := 'c0000035'O;
2461
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002462 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 +02002463
2464 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002465 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002466 /* break */
2467 }
Harald Welte955aa942019-05-03 01:29:29 +02002468 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002469 /* ignore ID REQ IMSI */
2470 count_req := count_req + 1;
2471 repeat;
2472 }
Harald Welte955aa942019-05-03 01:29:29 +02002473 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002474 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002475 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002476 repeat;
2477 }
2478 }
2479 if (count_req != 5) {
2480 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002481 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002482 }
2483 setverdict(pass);
2484}
2485
2486testcase TC_attach_no_imsi_response() runs on test_CT {
2487 /* MS -> SGSN: Attach Request TMSI (unknown)
2488 * MS <- SGSN: Identity Request IMEI (optional)
2489 * MS -> SGSN: Identity Response IMEI (optional)
2490 * MS <- SGSN: Identity Request IMSI
2491 * MS -x SGSN: no response
2492 * MS <- SGSN: re-send: Identity Request IMSI 4x
2493 * MS <- SGSN: Attach Reject
2494 */
2495 var BSSGP_ConnHdlr vc_conn;
2496 f_init();
2497 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002498 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 +02002499 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002500 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002501}
2502
Alexander Couzenscf818962018-06-05 18:00:00 +02002503private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2504 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2505}
2506
2507testcase TC_attach_check_subscriber_list() runs on test_CT {
2508 /* MS <-> SGSN: Attach
2509 * VTY -> SGSN: Check if MS is in subscriber cache
2510 */
2511 var BSSGP_ConnHdlr vc_conn;
2512 var integer id := 34;
2513 var charstring imsi := hex2str(f_gen_imsi(id));
2514
2515 f_init();
2516 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002517 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002518 vc_conn.done;
2519
2520 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2521 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002522 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002523}
2524
Alexander Couzensf9858652018-06-07 16:14:53 +02002525private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2526 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002527 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002528
2529 /* unregister the old IMSI */
2530 f_bssgp_client_unregister(g_pars.imsi);
2531 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002532 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002533 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002534
2535 /* there is no auth */
2536 g_pars.net.expect_auth := false;
2537
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002538 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002539 f_gmm_auth();
2540 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002541 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002542 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002543 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002544 }
Harald Welte955aa942019-05-03 01:29:29 +02002545 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2546 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002547 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002548 setverdict(pass);
2549 }
2550 }
2551}
Alexander Couzens03d12242018-08-07 16:13:52 +02002552
2553private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2554
2555 f_TC_attach_closed_foreign(id);
2556 f_TC_attach_closed_imsi_added(id);
2557
2558}
2559
2560
Alexander Couzensf9858652018-06-07 16:14:53 +02002561testcase TC_attach_closed_add_vty() runs on test_CT {
2562 /* VTY-> SGSN: policy close
2563 * MS -> SGSN: Attach Request
2564 * MS <- SGSN: Identity Request IMSI
2565 * MS -> SGSN: Identity Response IMSI
2566 * MS <- SGSN: Attach Reject
2567 * VTY-> SGSN: policy imsi-acl add IMSI
2568 * MS -> SGSN: Attach Request
2569 * MS <- SGSN: Identity Request IMSI
2570 * MS -> SGSN: Identity Response IMSI
2571 * MS <- SGSN: Identity Request IMEI
2572 * MS -> SGSN: Identity Response IMEI
2573 * MS <- SGSN: Attach Accept
2574 */
2575 var BSSGP_ConnHdlr vc_conn;
2576 f_init();
2577 f_sleep(1.0);
2578 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2579 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002580 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2581 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002582 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002583 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002584 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002585 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002586}
2587
Alexander Couzens0085bd72018-06-12 19:08:44 +02002588/* Attempt an attach, but never answer a Attach Complete */
2589private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2590 var integer count_req := 0;
2591
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002592 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 +02002593 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002594 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07002595 as_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002596
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002597 timer T := 10.0;
2598 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002599 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002600 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002601 /* break */
2602 }
Harald Welte955aa942019-05-03 01:29:29 +02002603 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002604 /* ignore */
2605 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002606 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002607 repeat;
2608 }
2609 }
2610 if (count_req != 5) {
2611 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002612 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002613 }
2614 setverdict(pass);
2615}
2616
2617testcase TC_attach_check_complete_resend() runs on test_CT {
2618 /* MS -> SGSN: Attach Request IMSI
2619 * MS <- SGSN: Identity Request *
2620 * MS -> SGSN: Identity Response *
2621 * MS <- SGSN: Attach Complete 5x
2622 */
2623 var BSSGP_ConnHdlr vc_conn;
2624 f_init();
2625 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002626 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 +02002627 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002628 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002629}
2630
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002631friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002632 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002633 var PDU_DTAP_PS_MT mt;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002634 var template (omit) OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002635
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002636 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002637 p_tmsi := g_pars.p_tmsi;
2638 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002639 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002640 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 +02002641 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002642 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2643 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2644 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002645 setverdict(pass);
2646 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002647 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2648 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2649 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002650 setverdict(pass);
2651 }
2652
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002653 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002654 setverdict(fail, "Unexpected RAU Reject");
2655 mtc.stop;
2656 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002657 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002658 setverdict(fail, "Unexpected RAU Reject");
2659 mtc.stop;
2660 }
2661
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002662 [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 +02002663 key_sts := ?)) {
2664 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2665 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002666 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002667 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002668 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002669 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2670 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002671 }
2672}
2673
Alexander Couzensbfda9212018-07-31 03:17:33 +02002674private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002675 /* first perform regular attach */
2676 f_TC_attach(id);
2677
2678 /* then send RAU */
2679 f_routing_area_update(g_pars.ra);
2680
2681 /* do another RAU */
2682 f_routing_area_update(g_pars.ra);
2683
2684 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2685}
2686
2687testcase TC_attach_rau_a_a() runs on test_CT {
2688 /* MS <-> SGSN: Successful Attach
2689 * MS -> SGSN: Routing Area Update Request
2690 * MS <- SGSN: Routing Area Update Accept
2691 * MS -> SGSN: Routing Area Update Request
2692 * MS <- SGSN: Routing Area Update Accept
2693 * MS -> SGSN: Detach (PowerOff)
2694 */
2695 var BSSGP_ConnHdlr vc_conn;
2696 f_init();
2697 f_sleep(1.0);
2698 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2699 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002700 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002701}
2702
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002703private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002704 f_TC_attach(id);
2705
2706 log("attach complete sending rau");
2707 f_routing_area_update(g_pars.ra, 0);
2708
2709 log("rau complete unregistering");
2710 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002711 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002712
2713 log("sending second RAU via different RA");
2714 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2715
2716 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2717}
2718
2719testcase TC_attach_rau_a_b() runs on test_CT {
2720 /* MS <-> SGSN: Successful Attach
2721 * MS -> SGSN: Routing Area _a_ Update Request
2722 * MS <- SGSN: Routing Area _a_ Update Accept
2723 * MS -> SGSN: Routing Area _b_ Update Request
2724 * MS <- SGSN: Routing Area _b_ Update Accept
2725 * MS -> SGSN: Detach (PowerOff)
2726 */
2727 var BSSGP_ConnHdlr vc_conn;
2728 f_init();
2729 f_sleep(1.0);
2730 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2731 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002732 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002733}
2734
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002735private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2736 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002737 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002738 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002739 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002740
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002741 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002742
2743 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002744 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002745 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2746 mtc.stop;
2747 }
Harald Welte955aa942019-05-03 01:29:29 +02002748 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002749 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002750 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002751 repeat;
2752 }
Harald Welte955aa942019-05-03 01:29:29 +02002753 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002754 /* send out a second GMM_Attach Request.
2755 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2756 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002757 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002758 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002759 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002760 }
2761 }
2762 f_sleep(1.0);
2763
2764 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2765 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002766 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002767 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002768 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002769 repeat;
2770 }
Harald Welte955aa942019-05-03 01:29:29 +02002771 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002772 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2773 mtc.stop;
2774 }
Harald Welte955aa942019-05-03 01:29:29 +02002775 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002776 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2777 mtc.stop;
2778 }
Harald Welte955aa942019-05-03 01:29:29 +02002779 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2780 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002781 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002782 setverdict(pass);
2783 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2784 }
2785 }
2786}
2787
2788testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2789 /* Testing if the SGSN ignore Attach Request with the exact same content */
2790 /* MS -> SGSN: Attach Request IMSI
2791 * MS <- SGSN: Identity Request IMSI (optional)
2792 * MS -> SGSN: Identity Response IMSI (optional)
2793 * MS <- SGSN: Identity Request IMEI
2794 * MS -> SGSN: Attach Request (2nd)
2795 * MS <- SGSN: Identity Response IMEI
2796 * MS <- SGSN: Attach Accept
2797 * MS -> SGSN: Attach Complete
2798 */
2799 var BSSGP_ConnHdlr vc_conn;
2800 f_init();
2801 f_sleep(1.0);
2802 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2803 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2804 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002805 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002806}
2807
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002808private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002809 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2810
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002811 var template (value) PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002812
2813 /* send Attach Request */
2814 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2815 * 3G auth vectors */
2816 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2817 /* The thing is, if the solSACapability is 'omit', then the
2818 * revisionLevelIndicatior is at the wrong place! */
2819 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002820 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002821
2822 /* do the auth */
2823 var PDU_L3_MS_SGSN l3_mo;
2824 var PDU_L3_SGSN_MS l3_mt;
2825 var default di := activate(as_mm_identity());
2826
2827 var GSUP_IE auth_tuple;
2828 var template AuthenticationParameterAUTNTLV autn;
2829
2830 g_pars.vec := f_gen_auth_vec_3g();
2831 autn := {
2832 elementIdentifier := '28'O,
2833 lengthIndicator := lengthof(g_pars.vec.autn),
2834 autnValue := g_pars.vec.autn
2835 };
2836 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2837 g_pars.vec.sres,
2838 g_pars.vec.kc,
2839 g_pars.vec.ik,
2840 g_pars.vec.ck,
2841 g_pars.vec.autn,
2842 g_pars.vec.res));
2843 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2844 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2845 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2846
2847 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2848 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002849 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002850
2851 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002852 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002853
2854 /* wait for the GSUP resync request */
2855 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2856 g_pars.imsi,
2857 g_pars.vec.auts,
2858 g_pars.vec.rand));
2859
2860 /* generate new key material */
2861 g_pars.vec := f_gen_auth_vec_3g();
2862 autn := {
2863 elementIdentifier := '28'O,
2864 lengthIndicator := lengthof(g_pars.vec.autn),
2865 autnValue := g_pars.vec.autn
2866 };
2867
2868 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2869 g_pars.vec.sres,
2870 g_pars.vec.kc,
2871 g_pars.vec.ik,
2872 g_pars.vec.ck,
2873 g_pars.vec.autn,
2874 g_pars.vec.res));
2875 /* send new key material */
2876 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2877
2878 /* wait for the new Auth Request */
2879 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2880 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002881 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002882 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002883 var template (value) PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002884 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2885 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2886 valueField := substr(g_pars.vec.res, 0, 4)
2887 };
2888 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2889 elementIdentifier := '21'O,
2890 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2891 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2892 };
2893 l3_mo := valueof(auth_ciph_resp);
2894 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2895 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2896 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2897 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2898 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002899 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002900 deactivate(di);
2901
2902 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07002903 as_gmm_gsup_lu_isd();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002904
Harald Welte955aa942019-05-03 01:29:29 +02002905 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2906 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002907 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002908 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002909 setverdict(pass);
2910}
2911
2912testcase TC_attach_usim_resync() runs on test_CT {
2913 /* MS -> SGSN: Attach Request
2914 * MS <- SGSN: Identity Request IMSI
2915 * MS -> SGSN: Identity Response IMSI
2916 * MS <- SGSN: Identity Request IMEI
2917 * MS -> SGSN: Identity Response IMEI
2918 * HLR<- SGSN: SAI Request
2919 * HLR-> SGSN: SAI Response
2920 * MS <- SGSN: Auth Request
2921 * MS -> SGSN: Auth Failure (with AUTS)
2922 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2923 * HLR-> SGSN: SAI Response (new key material)
2924 * MS <- SGSN: Auth Request (new key material)
2925 * MS -> SGSN: Auth Response
2926 * MS <- SGSN: Attach Accept
2927 * MS -> SGSN: Attach Complete
2928 */
2929 var BSSGP_ConnHdlr vc_conn;
2930 f_init();
2931 f_sleep(1.0);
2932 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2933 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002934 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002935}
2936
Eric Wildc555be52021-05-15 19:48:22 +02002937private function f_TC_attach_usim_crypt(OCT1 netcap_a2345, BIT3 auth_req_ciph) runs on BSSGP_ConnHdlr {
2938 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2939
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002940 var template (value) PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Eric Wildc555be52021-05-15 19:48:22 +02002941 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.spare_octets := netcap_a2345; /* GEA2345... */
2942
2943 /* send Attach Request */
2944 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2945 * 3G auth vectors */
2946 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2947 /* The thing is, if the solSACapability is 'omit', then the
2948 * revisionLevelIndicatior is at the wrong place! */
2949 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2950 f_send_l3(attach_req);
2951
2952 /* do the auth */
2953 var PDU_L3_MS_SGSN l3_mo;
2954 var PDU_L3_SGSN_MS l3_mt;
2955 var default di := activate(as_mm_identity());
2956
2957 var GSUP_IE auth_tuple;
2958 var template AuthenticationParameterAUTNTLV autn;
2959
2960 g_pars.vec := f_gen_auth_vec_3g();
2961 autn := {
2962 elementIdentifier := '28'O,
2963 lengthIndicator := lengthof(g_pars.vec.autn),
2964 autnValue := g_pars.vec.autn
2965 };
2966 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2967 g_pars.vec.sres,
2968 g_pars.vec.kc,
2969 g_pars.vec.ik,
2970 g_pars.vec.ck,
2971 g_pars.vec.autn,
2972 g_pars.vec.res));
2973 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2974 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2975 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2976
2977 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand, auth_req_ciph);
2978 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2979 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
2980
2981 setverdict(pass);
2982 deactivate(di);
2983}
2984
2985private function f_TC_attach_usim_a54_a54(charstring id) runs on BSSGP_ConnHdlr {
2986 f_TC_attach_usim_crypt('10'O, '100'B);
2987}
2988
2989private function f_TC_attach_usim_a54_a53(charstring id) runs on BSSGP_ConnHdlr {
2990 f_TC_attach_usim_crypt('20'O, '011'B);
2991}
2992
2993private function f_TC_attach_usim_a53_a54(charstring id) runs on BSSGP_ConnHdlr {
2994 f_TC_attach_usim_crypt('30'O, '011'B);
2995}
2996
2997private function f_TC_attach_usim_a50_a54(charstring id) runs on BSSGP_ConnHdlr {
2998 f_TC_attach_usim_crypt('30'O, '000'B);
2999}
3000
3001private function f_TC_attach_usim_a54_a50(charstring id) runs on BSSGP_ConnHdlr {
3002 f_TC_attach_usim_crypt('00'O, '000'B);
3003}
3004
3005testcase TC_attach_usim_a54_a54() runs on test_CT {
3006 var BSSGP_ConnHdlr vc_conn;
3007 f_init();
3008 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003009 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003010 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a54), testcasename(), g_gb, 40);
3011 vc_conn.done;
3012 f_cleanup();
3013}
3014
3015testcase TC_attach_usim_a54_a53() runs on test_CT {
3016 var BSSGP_ConnHdlr vc_conn;
3017 f_init();
3018 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003019 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003020 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a53), testcasename(), g_gb, 40);
3021 vc_conn.done;
3022 f_cleanup();
3023}
3024
3025testcase TC_attach_usim_a53_a54() runs on test_CT {
3026 var BSSGP_ConnHdlr vc_conn;
3027 f_init();
3028 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003029 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3");
Eric Wildc555be52021-05-15 19:48:22 +02003030 vc_conn := f_start_handler(refers(f_TC_attach_usim_a53_a54), testcasename(), g_gb, 40);
3031 vc_conn.done;
3032 f_cleanup();
3033}
3034
3035testcase TC_attach_usim_a50_a54() runs on test_CT {
3036 var BSSGP_ConnHdlr vc_conn;
3037 f_init();
3038 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003039 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0");
Eric Wildc555be52021-05-15 19:48:22 +02003040 vc_conn := f_start_handler(refers(f_TC_attach_usim_a50_a54), testcasename(), g_gb, 40);
3041 vc_conn.done;
3042 f_cleanup();
3043}
3044
3045testcase TC_attach_usim_a54_a50() runs on test_CT {
3046 var BSSGP_ConnHdlr vc_conn;
3047 f_init();
3048 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003049 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003050 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a50), testcasename(), g_gb, 40);
3051 vc_conn.done;
3052 f_cleanup();
3053}
Harald Weltea05b8072019-04-23 22:35:05 +02003054
3055/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
3056private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
3057 f_gmm_attach(false, false);
3058 f_sleep(1.0);
3059 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
3060 /* try to detach to check if SGSN is still alive */
3061 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
3062}
3063testcase TC_llc_null() runs on test_CT {
3064 var BSSGP_ConnHdlr vc_conn;
3065 f_init();
3066 f_sleep(1.0);
3067 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
3068 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003069 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02003070}
3071
Harald Welte645a1512019-04-23 23:18:23 +02003072/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3073private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
3074 f_gmm_attach(false, false);
3075 f_sleep(1.0);
3076 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003077 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003078 setverdict(pass);
3079}
3080testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
3081 var BSSGP_ConnHdlr vc_conn;
3082 f_init();
3083 f_sleep(1.0);
3084 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
3085 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003086 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003087}
3088
3089/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3090private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
3091 f_gmm_attach(false, false);
3092 f_sleep(1.0);
3093 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003094 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003095 setverdict(pass);
3096}
3097testcase TC_llc_sabm_dm_ll5() runs on test_CT {
3098 var BSSGP_ConnHdlr vc_conn;
3099 f_init();
3100 f_sleep(1.0);
3101 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
3102 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003103 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003104}
3105
Harald Welte2aaac1b2019-05-02 10:02:53 +02003106/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
3107private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
3108 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3109 var template (value) XID_Information xid;
3110 var template XID_Information xid_rx;
3111
3112 /* first perform regular attach */
3113 f_TC_attach(id);
3114 /* then activate PDP context */
3115 f_pdp_ctx_act(apars);
3116
3117 /* start MO XID */
3118 xid := { ts_XID_L3(''O) };
3119 xid_rx := { tr_XID_L3(''O) };
3120 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3121 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003122 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003123 [] as_xid(apars);
3124 }
3125 setverdict(pass);
3126}
3127testcase TC_xid_empty_l3() runs on test_CT {
3128 var BSSGP_ConnHdlr vc_conn;
3129 f_init();
3130 f_sleep(1.0);
3131 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
3132 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003133 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003134}
3135
3136private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
3137 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3138 var template (value) XID_Information xid;
3139 var template XID_Information xid_rx;
3140
3141 /* first perform regular attach */
3142 f_TC_attach(id);
3143 /* then activate PDP context */
3144 f_pdp_ctx_act(apars);
3145
3146 /* start MO XID */
3147 xid := { ts_XID_N201U(1234) };
3148 xid_rx := { tr_XID_N201U(1234) };
3149 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3150 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003151 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003152 [] as_xid(apars);
3153 }
3154 setverdict(pass);
3155}
3156testcase TC_xid_n201u() runs on test_CT {
3157 var BSSGP_ConnHdlr vc_conn;
3158 f_init();
3159 f_sleep(1.0);
3160 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
3161 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003162 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003163}
3164
Alexander Couzens6bee0872019-05-11 01:48:50 +02003165private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
3166 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3167
3168 /* first perform regular attach */
3169 f_TC_attach(id);
3170 /* then activate PDP context */
3171 f_pdp_ctx_act(apars);
3172 /* do a normal detach */
3173 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
3174}
3175
3176testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
3177 /* MS -> SGSN: Attach Request
3178 * MS <-> SGSN: [..]
3179 * MS -> SGSN: Attach Complete
3180 * MS -> SGSN: PDP Activate Request
3181 * MS <- SGSN: PDP Activate Accept
3182 * MS -> SGSN: GMM Detach Request
3183 * MS <- SGSN: GMM Detach Accept
3184 */
3185 var BSSGP_ConnHdlr vc_conn;
3186 f_init();
3187 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
3188 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003189 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02003190}
Harald Welte645a1512019-04-23 23:18:23 +02003191
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003192private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
3193 var RoutingAreaIdentificationV old_ra := f_random_RAI();
3194 var RoutingAreaIdentificationV new_ra := f_random_RAI();
3195 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003196 var template (value) PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003197 var PDU_L3_SGSN_MS l3_mt;
3198
3199 f_send_l3(attach_req, 0);
3200
3201 BSSGP[0].receive(tr_GMM_ID_REQ(?));
3202
3203 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
3204 alt {
3205 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
3206 setverdict(pass);
3207 }
3208 [] BSSGP[0].receive { repeat; }
3209 }
3210}
3211
3212/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
3213 * See OS#3957 and OS#4245 for more information.
3214 */
3215testcase TC_attach_req_id_req_ra_update() runs on test_CT {
3216 /*
3217 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
3218 * MS <-- SGSN: Identity Request (IMEI)
3219 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
3220 */
3221 var BSSGP_ConnHdlr vc_conn;
3222 f_init();
3223 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
3224 vc_conn.done;
3225 f_cleanup();
3226}
3227
Harald Welte8e5932e2020-06-17 22:12:54 +02003228private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
3229var PDU_BSSGP rx;
3230[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
3231 setverdict(fail, "Received unexpected PS PAGING: ", rx);
3232 mtc.stop;
3233 }
3234}
3235
3236/* SUSPEND, then DL traffic: should not pass + no paging expected */
3237private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3238 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3239 var default d;
3240
3241 /* first perform regular attach */
3242 f_TC_attach(id);
3243 /* then activate PDP context */
3244 f_pdp_ctx_act(apars);
3245 /* then transceive a downlink PDU */
3246 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3247
3248 /* now suspend GPRS */
3249 f_bssgp_suspend();
3250
3251 d := activate(as_nopaging_ps());
3252
3253 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3254 * nor any related paging requests */
3255 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3256
3257 deactivate(d);
3258}
3259testcase TC_suspend_nopaging() runs on test_CT {
3260 var BSSGP_ConnHdlr vc_conn;
3261 f_init();
3262 f_sleep(1.0);
3263 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3264 vc_conn.done;
3265 f_cleanup();
3266}
3267
3268
3269/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3270private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3271 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3272 var OCT1 susp_ref;
3273 var default d;
3274
3275 /* first perform regular attach */
3276 f_TC_attach(id);
3277 /* then activate PDP context */
3278 f_pdp_ctx_act(apars);
3279 /* then transceive a downlink PDU */
3280 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3281
3282 /* now suspend GPRS */
3283 susp_ref := f_bssgp_suspend();
3284
3285 d := activate(as_nopaging_ps());
3286
3287 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3288 * nor any related paging requests */
3289 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3290
3291 deactivate(d);
3292
3293 /* resume GPRS */
3294 f_bssgp_resume(susp_ref);
3295
3296 /* now data should be flowing again */
3297 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3298}
3299testcase TC_suspend_resume() runs on test_CT {
3300 var BSSGP_ConnHdlr vc_conn;
3301 f_init();
3302 f_sleep(1.0);
3303 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3304 vc_conn.done;
3305 f_cleanup();
3306}
3307
3308/* SUSPEND, then RAU: data expected to flow after implicit resume */
3309private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3310 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3311 var default d;
3312
3313 /* first perform regular attach */
3314 f_TC_attach(id);
3315 /* then activate PDP context */
3316 f_pdp_ctx_act(apars);
3317 /* then transceive a downlink PDU */
3318 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3319
3320 /* now suspend GPRS */
3321 f_bssgp_suspend();
3322
3323 d := activate(as_nopaging_ps());
3324
3325 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3326 * nor any related paging requests */
3327 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3328
3329 deactivate(d);
3330
3331 /* perform RAU (implicit RESUME) */
3332 f_routing_area_update(g_pars.ra);
3333
Harald Welted5836dc2021-03-20 15:40:00 +01003334 /* give SGSN some time to actually receve + process the RAU Complete we sent */
3335 f_sleep(0.5);
3336
Harald Welte8e5932e2020-06-17 22:12:54 +02003337 /* now data should be flowing again */
3338 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3339
3340}
3341testcase TC_suspend_rau() runs on test_CT {
3342 var BSSGP_ConnHdlr vc_conn;
3343 f_init();
3344 f_sleep(1.0);
3345 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3346 vc_conn.done;
3347 f_cleanup();
3348}
3349
3350
3351/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3352private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3353 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3354 var default d;
3355
3356 /* first perform regular attach */
3357 f_TC_attach(id);
3358 /* then activate PDP context */
3359 f_pdp_ctx_act(apars);
3360 /* then transceive a downlink PDU */
3361 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3362
3363 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3364 f_sleep(5.0);
3365
3366 /* now data should be flowing again, but with PS PAGING */
3367 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3368 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3369
3370 /* FIXME: simulate paging response */
3371 /* FIXME: verify PDU actually arrives only after paging response was successful */
3372
3373}
3374testcase TC_paging_ps() runs on test_CT {
3375 var BSSGP_ConnHdlr vc_conn;
3376 f_init();
3377 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3378 f_sleep(1.0);
3379 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3380 vc_conn.done;
3381 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3382 f_cleanup();
3383}
3384
Philipp Maier7df55e02020-12-14 23:46:04 +01003385/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3386 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3387 * other and vice versa. */
3388testcase TC_bssgp_rim_single_report() runs on test_CT {
3389 var BSSGP_ConnHdlr vc_conn;
3390 f_init();
Philipp Maier7df55e02020-12-14 23:46:04 +01003391
3392 timer T := 2.0;
3393
3394 var template RIM_Routing_Address dst_addr;
3395 var template RIM_Routing_Address src_addr;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003396 var template (value) RAN_Information_Request_RIM_Container req_cont;
3397 var template (value) RAN_Information_RIM_Container res_cont;
3398 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maier7df55e02020-12-14 23:46:04 +01003399 var template PDU_BSSGP bssgp_rim_pdu_expect;
3400
3401 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3402 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003403
3404
Philipp Maier7df55e02020-12-14 23:46:04 +01003405 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3406 * based on the cell id in dst_addr to GB interface #1. */
3407 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3408 ts_RIM_Sequence_Number(1),
3409 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3410 ts_RIM_Protocol_Version_Number(1),
3411 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3412 omit);
3413 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3414 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3415 req_cont);
3416 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3417 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3418 tr_RAN_Information_Request_RIM_Container);
3419 RIM[0].send(bssgp_rim_pdu);
3420 T.start;
3421 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003422 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3423 setverdict(pass);
3424 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003425 [] RIM[1].receive {
3426 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003427 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003428 [] T.timeout {
3429 setverdict(fail, "No BSSGP RIM PDU received");
3430 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003431 }
3432 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003433
Philipp Maier7df55e02020-12-14 23:46:04 +01003434 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3435 * GB interface #0 */
Philipp Maier7df55e02020-12-14 23:46:04 +01003436 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3437 ts_RIM_Sequence_Number(2),
3438 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3439 ts_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003440 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si_default)),
Philipp Maier7df55e02020-12-14 23:46:04 +01003441 omit);
3442 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3443 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3444 res_cont);
3445 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3446 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3447 ?);
3448 RIM[1].send(bssgp_rim_pdu);
3449 T.start;
3450 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003451 [] RIM[0].receive(bssgp_rim_pdu_expect) {
3452 setverdict(pass);
3453 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003454 [] RIM[0].receive {
3455 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003456 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003457 [] T.timeout {
3458 setverdict(fail, "No BSSGP RIM PDU received");
3459 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003460 }
3461 }
3462
3463 f_cleanup();
3464}
Harald Welte8e5932e2020-06-17 22:12:54 +02003465
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003466testcase TC_rim_eutran_to_geran() runs on test_CT {
3467 var BSSGP_ConnHdlr vc_conn;
3468 f_init();
3469 /* connect RIM related port */
3470 connect(vc_GTP:CLIENT_DEFAULT, self:GTPC);
3471
3472 var GtpPeer peer := {
3473 connId := 1,
3474 remName := mp_sgsn_gtp_ip,
3475 remPort := GTP1C_PORT
3476 }
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003477 var GTP_CellId gtp_ci := f_BssgpCellId_to_GTP_CellId(g_gb[1].cfg.bvc[0].cell_id);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003478
3479 var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
3480 var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
3481 var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
Philipp Maier7e9acc32023-08-04 17:23:12 +02003482 var template (value) RIM_RoutingAddress gtpc_rim_ra;
3483 var template (value) RIM_RoutingAddress_Discriminator gtpc_rim_ra_discr;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003484 var template (value) Gtp1cUnitdata gtpc_pdu;
3485
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003486 gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(gtp_ci);
3487 gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(gtp_ci, tac := 3, gnbid := '12345678123456'O);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003488
3489 gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3490 ts_GTPC_RIM_Sequence_Number(1),
3491 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3492 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003493 tsu_GTPC_RAN_Information_Request_Application_Container_NACC(gtp_ci),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003494 omit);
3495 gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3496 ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3497 gtpc_rim_req_cont);
Philipp Maier7e9acc32023-08-04 17:23:12 +02003498
3499 /* Assemble RIM Routing Address (essentially a copy of the destination cell identifier)*/
3500 gtpc_rim_ra := ts_RIM_RoutingAddress(enc_RIM_Routing_Address_GTPC(valueof(gtpc_dst_addr)));
3501 gtpc_rim_ra_discr := ts_RIM_RoutingAddress_Discriminator(hex2bit(RIM_ADDR_GERAN_CELL_ID));
3502 gtpc_pdu := ts_GTPC_RANInfoRelay(peer, ts_RANTransparentContainer_RAN_INFO_REQ(gtpc_bssgp_cont),
3503 gtpc_rim_ra, gtpc_rim_ra_discr);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003504 GTPC.send(gtpc_pdu);
3505
3506 var template RIM_Routing_Address bssgp_dst_addr, bssgp_src_addr;
3507 var template PDU_BSSGP bssgp_rim_pdu_expect;
3508 bssgp_dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3509 bssgp_src_addr := t_RIM_Routing_Address_enbid(g_gb[1].cfg.bvc[0].cell_id, tac := 3, gnbid := '12345678123456'O);
3510 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3511 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3512 tr_RAN_Information_Request_RIM_Container);
3513 timer T := 2.0;
3514 T.start;
3515 alt {
3516 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3517 setverdict(pass);
3518 T.stop;
3519 }
3520 [] RIM[1].receive {
3521 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3522 }
3523 [] T.timeout {
3524 setverdict(fail, "No BSSGP RIM PDU received");
3525 mtc.stop;
3526 }
3527 }
3528
3529 /* Now also emulate also the response as well and send it back on GB
3530 interface #1. Expect the result on * GTPC */
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003531 var template (value) RAN_Information_RIM_Container res_cont;
3532 var template (value) PDU_BSSGP bssgp_rim_pdu;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003533 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3534 ts_RIM_Sequence_Number(2),
3535 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3536 ts_RIM_Protocol_Version_Number(1),
3537 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[1].cfg.bvc[0].cell_id, false, 3, si_default)),
3538 omit);
3539 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3540 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3541 res_cont);
3542 RIM[1].send(bssgp_rim_pdu);
3543
3544 var template RAN_Information_RIM_Container_GTPC rim_cont;
3545 var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_cont_ack;
3546 var template Gtp1cUnitdata gtpc_pdu_exp;
3547 rim_cont := tr_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3548 ts_GTPC_RIM_Sequence_Number(2),
3549 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3550 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003551 tru_GTPC_ApplContainer_or_ApplErrContainer_NACC(tru_GTPC_ApplContainer_NACC(gtp_ci, false, 3, si_default)),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003552 omit);
3553 gtpc_bssgp_cont_ack := tr_GTPC_RAN_Information(tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3554 tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3555 rim_cont);
3556 gtpc_pdu_exp := tr_GTPC_RANInfoRelay(peer, tr_RANTransparentContainer_RAN_INFO(gtpc_bssgp_cont_ack));
3557
3558 T.start;
3559 alt {
3560 [] GTPC.receive(gtpc_pdu_exp) {
3561 setverdict(pass);
3562 T.stop;
3563 }
3564 [] GTPC.receive {
3565 setverdict(fail, "Unexpected GTPC RIM PDU received");
3566 }
3567 [] T.timeout {
3568 setverdict(fail, "No GTPC RIM PDU received");
3569 mtc.stop;
3570 }
3571 }
3572
3573 f_cleanup();
3574}
3575
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003576/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3577private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3578 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3579
3580 /* first perform regular attach */
3581 f_gmm_attach(false, false, ran_index := 0);
3582 /* then activate PDP context */
3583 f_pdp_ctx_act(apars, ran_index := 0);
3584 /* then transceive a downlink PDU */
3585 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3586 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3587
3588 /* Now attach on different cell: */
3589 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3590 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3591 g_pars.net.expect_auth := false;
3592 f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0]));
3593 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3594 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1);
3595}
3596testcase TC_cell_change_different_rai_ci_attach() runs on test_CT {
3597 var BSSGP_ConnHdlr vc_conn;
3598 f_init();
3599 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68);
3600 vc_conn.done;
3601 f_cleanup();
3602}
3603
3604/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3605/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3606private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3607 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3608
3609 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3610 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3611
3612 /* first perform regular attach */
3613 f_gmm_attach(false, false, ran_index := 1);
3614 /* then activate PDP context */
3615 f_pdp_ctx_act(apars, ran_index := 1);
3616 /* then transceive a downlink PDU */
3617 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3618 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3619
3620 /* Now attach on different cell: */
3621 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3622 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3623 g_pars.net.expect_auth := false;
3624 f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1]));
3625 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3626 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3627}
3628testcase TC_cell_change_different_ci_attach() runs on test_CT {
3629 var BSSGP_ConnHdlr vc_conn;
3630 f_init();
3631 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69);
3632 vc_conn.done;
3633 f_cleanup();
3634}
3635
3636/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */
3637private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3638 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3639
3640 /* first perform regular attach */
3641 f_gmm_attach(false, false, ran_index := 0);
3642 /* then activate PDP context */
3643 f_pdp_ctx_act(apars, ran_index := 0);
3644 /* then transceive a downlink PDU */
3645 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3646 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3647
3648 /* Send some data over new bvci, it should be silently discarded since
3649 * RAC changed and SGSN expects a RAU to occur in that case */
3650 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3651 var octetstring payload := f_rnd_octstring(200);
3652 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
3653 BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1));
3654 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
3655 timer T := 2.0;
3656 T.start;
3657 alt {
3658 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) {
3659 setverdict(fail, "Unexpected GTP message");
3660 }
3661 [] T.timeout { setverdict(pass); }
3662 }
3663
3664 /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */
3665 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3666 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3667}
3668testcase TC_cell_change_different_rai_ci_data() runs on test_CT {
3669 var BSSGP_ConnHdlr vc_conn;
3670 f_init();
3671 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70);
3672 vc_conn.done;
3673 f_cleanup();
3674}
3675
3676/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */
3677/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3678private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3679 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3680
3681 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3682 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3683
3684 /* first perform regular attach */
3685 f_gmm_attach(false, false, ran_index := 1);
3686 /* then activate PDP context */
3687 f_pdp_ctx_act(apars, ran_index := 1);
3688 /* then transceive a downlink PDU */
3689 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3690 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3691
3692 /* Now attach on different cell: */
3693 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3694 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3695
3696 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3697 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3698}
3699testcase TC_cell_change_different_ci_data() runs on test_CT {
3700 var BSSGP_ConnHdlr vc_conn;
3701 f_init();
3702 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71);
3703 vc_conn.done;
3704 f_cleanup();
3705}
3706
Harald Welte5ac31492018-02-15 20:39:13 +01003707control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003708 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003709 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003710 execute( TC_attach_umts_aka_umts_res() );
3711 execute( TC_attach_umts_aka_gsm_sres() );
arehbein3ede9e32023-02-06 21:02:53 +01003712 execute( TC_attach_timeout_after_pdp_act() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003713 execute( TC_attach_auth_id_timeout() );
3714 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003715 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003716 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003717 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003718 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003719 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003720 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003721 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003722 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003723 execute( TC_attach_closed_add_vty(), 20.0 );
3724 execute( TC_attach_check_subscriber_list(), 20.0 );
3725 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003726 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003727 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3728 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3729 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3730 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003731 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003732 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003733 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003734 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003735 execute( TC_attach_usim_resync() );
Eric Wildc555be52021-05-15 19:48:22 +02003736 execute( TC_attach_usim_a54_a54() );
3737 execute( TC_attach_usim_a54_a53() );
3738 execute( TC_attach_usim_a53_a54() );
3739 execute( TC_attach_usim_a50_a54() );
3740 execute( TC_attach_usim_a54_a50() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003741 execute( TC_detach_unknown_nopoweroff() );
3742 execute( TC_detach_unknown_poweroff() );
3743 execute( TC_detach_nopoweroff() );
3744 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003745 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003746 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003747 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003748 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003749 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003750 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003751 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003752 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003753 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003754 execute( TC_attach_restart_ctr_echo() );
3755 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003756 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003757 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3758 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003759 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003760 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003761 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003762
Harald Welte2aaac1b2019-05-02 10:02:53 +02003763 execute( TC_xid_empty_l3() );
3764 execute( TC_xid_n201u() );
3765
Harald Weltea05b8072019-04-23 22:35:05 +02003766 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003767 execute( TC_llc_sabm_dm_llgmm() );
3768 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003769
Harald Welte8e5932e2020-06-17 22:12:54 +02003770 execute( TC_suspend_nopaging() );
3771 execute( TC_suspend_resume() );
3772 execute( TC_suspend_rau() );
3773 execute( TC_paging_ps() );
3774
Philipp Maier7df55e02020-12-14 23:46:04 +01003775 execute( TC_bssgp_rim_single_report() );
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003776 execute( TC_rim_eutran_to_geran() );
Philipp Maier7df55e02020-12-14 23:46:04 +01003777
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003778 execute( TC_cell_change_different_rai_ci_attach() );
3779 execute( TC_cell_change_different_rai_ci_data() );
3780 execute( TC_cell_change_different_ci_attach() );
3781 execute( TC_cell_change_different_ci_data() );
3782
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003783 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3784 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003785}
Harald Welte96a33b02018-02-04 10:36:22 +01003786
3787
3788
3789}