blob: 0371e2933cd247465f81561f4ae26ad095dd0ed4 [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
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +010045import from GTPv1C_CodecPort all;
46import from GTPv1U_CodecPort all;
Harald Welteeded9ad2018-02-17 20:57:34 +010047import from GTPC_Types all;
48import from GTPU_Types all;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +010049import from GTPv1C_Templates all;
50import from GTPv1U_Templates all;
51import from GTP_Emulation all;
Harald Welteeded9ad2018-02-17 20:57:34 +010052
Harald Weltea2526a82018-02-18 19:03:36 +010053import from LLC_Types all;
54import from LLC_Templates all;
55
56import from SNDCP_Types all;
57
Harald Weltebd194722018-02-16 22:11:08 +010058import from TELNETasp_PortType all;
59import from Osmocom_VTY_Functions all;
60
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020061import from MobileL3_MM_Types all;
62
Harald Welteeded9ad2018-02-17 20:57:34 +010063
Harald Welte5ac31492018-02-15 20:39:13 +010064modulepar {
65 /* IP/port on which we run our internal GSUP/HLR emulation */
66 charstring mp_hlr_ip := "127.0.0.1";
67 integer mp_hlr_port := 4222;
Pau Espin Pedrol7bac69f2021-05-04 15:53:06 +020068 charstring mp_ggsn_ip := "127.0.0.103";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020069 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +020070 charstring mp_sgsn_gtp_ip := "127.0.0.10";
Alexander Couzens2c12b242018-07-31 00:30:11 +020071
Alexander Couzensf3c1b412018-08-24 00:42:51 +020072 NSConfigurations mp_nsconfig := {
73 {
Harald Welte5e514fa2018-07-05 00:01:45 +020074 nsei := 96,
75 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010076 handle_sns := false,
77 nsvc := {
78 {
79 provider := {
80 ip := {
81 address_family := AF_INET,
82 local_udp_port := 21010,
83 local_ip := "127.0.0.1",
84 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010085 remote_ip := "127.0.0.1",
86 data_weight := 1,
87 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010088 }
89 },
90 nsvci := 97
91 }
92 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020093 },
94 {
Harald Welte5e514fa2018-07-05 00:01:45 +020095 nsei := 97,
96 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010097 handle_sns := false,
98 nsvc := {
99 {
100 provider := {
101 ip := {
102 address_family := AF_INET,
103 local_udp_port := 21011,
104 local_ip := "127.0.0.1",
105 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100106 remote_ip := "127.0.0.1",
107 data_weight := 1,
108 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100109 }
110 },
111 nsvci := 98
112 }
113 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200114 },
115 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200116 nsei := 98,
117 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100118 handle_sns := false,
119 nsvc := {
120 {
121 provider := {
122 ip := {
123 address_family := AF_INET,
124 local_udp_port := 21012,
125 local_ip := "127.0.0.1",
126 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100127 remote_ip := "127.0.0.1",
128 data_weight := 1,
129 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100130 }
131 },
132 nsvci := 99
133 }
134 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200135 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200136 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200137
138 RAN_Configurations mp_ranap_cfg := {
139 {
140 transport := RANAP_TRANSPORT_IuCS,
141 sccp_service_type := "mtp3_itu",
142 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
143 own_pc := 195,
144 own_ssn := 142,
145 peer_pc := 188, /* 0.23.4 */
146 peer_ssn := 142,
147 sio := '83'O,
148 rctx := 2
149 }
150 }
Harald Welte5ac31492018-02-15 20:39:13 +0100151};
152
Harald Welte5339b2e2020-10-04 22:52:56 +0200153const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100154type record GbInstance {
155 NS_CT vc_NS,
156 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200157 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100158 BssgpConfig cfg
159};
Harald Welte96a33b02018-02-04 10:36:22 +0100160
Harald Welte2fa771f2019-05-02 20:13:53 +0200161const integer NUM_GB := 3;
162type record length(NUM_GB) of GbInstance GbInstances;
163type record length(NUM_GB) of NSConfiguration NSConfigurations;
164type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200165
Harald Welte26fbb6e2019-04-14 17:32:46 +0200166const integer NUM_RNC := 1;
167type record of RAN_Configuration RAN_Configurations;
168
Harald Welte96a33b02018-02-04 10:36:22 +0100169type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200170 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200171 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200172 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100173
Harald Welte5ac31492018-02-15 20:39:13 +0100174 var GSUP_Emulation_CT vc_GSUP;
175 var IPA_Emulation_CT vc_GSUP_IPA;
176 /* only to get events from IPA underneath GSUP */
177 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100178
Harald Welte5339b2e2020-10-04 22:52:56 +0200179 /* only needed at start to get the per-BVC references */
180 port BSSGP_CT_PROC_PT PROC;
181
Philipp Maier7df55e02020-12-14 23:46:04 +0100182 /* used by RIM related test */
183 port BSSGP_PT RIM[NUM_GB];
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +0200184 port GTPEM_PT GTPC;
Philipp Maier7df55e02020-12-14 23:46:04 +0100185
Harald Welteeded9ad2018-02-17 20:57:34 +0100186 var GTP_Emulation_CT vc_GTP;
187
Harald Weltebd194722018-02-16 22:11:08 +0100188 port TELNETasp_PT SGSNVTY;
189
Harald Welte96a33b02018-02-04 10:36:22 +0100190 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200191 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100192};
193
Harald Welte26fbb6e2019-04-14 17:32:46 +0200194type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100195 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100196 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200197 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100198}
199
200type record SGSN_ConnHdlrNetworkPars {
201 boolean expect_ptmsi,
202 boolean expect_auth,
203 boolean expect_ciph
204};
205
206type record BSSGP_ConnHdlrPars {
207 /* IMEI of the simulated ME */
208 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200209 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100210 hexstring imsi,
211 /* MSISDN of the simulated MS (probably unused) */
212 hexstring msisdn,
213 /* P-TMSI allocated to the simulated MS */
214 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100215 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100216 /* TLLI of the simulated MS */
217 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100218 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100219 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200220 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200221 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
222 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100223 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100224 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200225 float t_guard,
226 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200227 SCCP_PAR_Address sccp_addr_local optional,
228 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100229};
230
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +0200231/* Passed in RAN-INFO message from emulated neighbor using RIM */
232const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
233const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
234const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
235const octetstring si_default := si1_default & si3_default & si13_default;
236
Alexander Couzens89508702018-07-31 04:16:10 +0200237private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200238 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200239 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
240
241 var RoutingAreaIdentificationV ret := {
242 mccDigit1 := mcc_mnc[0],
243 mccDigit2 := mcc_mnc[1],
244 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200245 mncDigit3 := mcc_mnc[3],
246 mncDigit1 := mcc_mnc[4],
247 mncDigit2 := mcc_mnc[5],
Pau Espin Pedroldeaaa902021-02-12 18:41:04 +0100248 lac := int2oct(cell_id.ra_id.lai.lac, 2),
249 rac := int2oct(cell_id.ra_id.rac, 1)
Alexander Couzens89508702018-07-31 04:16:10 +0200250 }
251 return ret;
252};
253
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +0100254private function f_BssgpCellId_to_GTP_CellId(in BssgpCellId cell_id) return GTP_CellId
255{
256 template (value) GTP_CellId ret := ts_GTP_CellId(cell_id.ra_id, cell_id.cell_id);
257 return valueof(ret);
258}
259
Alexander Couzens51114d12018-07-31 18:41:56 +0200260private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Pau Espin Pedrol494e8b32022-02-22 16:46:23 +0100261 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset)) alive;
262 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset)) alive;
Harald Welte5ac31492018-02-15 20:39:13 +0100263 /* connect lower end of BSSGP emulation with NS upper port */
264 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100265
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200266 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200267 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
268 /* resolve the per-BVC component references */
269 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
270 connect(self:PROC, gb.vc_BSSGP:PROC);
271 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
272 disconnect(self:PROC, gb.vc_BSSGP:PROC);
273 }
Philipp Maier7df55e02020-12-14 23:46:04 +0100274 /* connect RIM related port */
275 connect(gb.vc_BSSGP:RIM, self:RIM[offset]);
Harald Welte5ac31492018-02-15 20:39:13 +0100276}
277
278private function f_init_gsup(charstring id) runs on test_CT {
279 id := id & "-GSUP";
280 var GsupOps ops := {
281 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
282 };
283
284 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
285 vc_GSUP := GSUP_Emulation_CT.create(id);
286
287 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
288 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
289 /* we use this hack to get events like ASP_IPA_EVENT_UP */
290 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
291
292 vc_GSUP.start(GSUP_Emulation.main(ops, id));
293 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
294
295 /* wait for incoming connection to GSUP port before proceeding */
296 timer T := 10.0;
297 T.start;
298 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700299 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100300 [] T.timeout {
301 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200302 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100303 }
304 }
305}
306
Harald Welteeded9ad2018-02-17 20:57:34 +0100307private function f_init_gtp(charstring id) runs on test_CT {
308 id := id & "-GTP";
309
310 var GtpEmulationCfg gtp_cfg := {
311 gtpc_bind_ip := mp_ggsn_ip,
312 gtpc_bind_port := GTP1C_PORT,
313 gtpu_bind_ip := mp_ggsn_ip,
314 gtpu_bind_port := GTP1U_PORT,
315 sgsn_role := false
316 };
317
318 vc_GTP := GTP_Emulation_CT.create(id);
319 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
320}
321
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200322friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100323 map(self:SGSNVTY, system:SGSNVTY);
324 f_vty_set_prompts(SGSNVTY);
325 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200326 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100327 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
328}
329
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200330private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
331 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200332 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200333 } else {
334 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
335 }
336}
337
Harald Weltebd194722018-02-16 22:11:08 +0100338
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200339/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
340function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200341 var integer i;
342
Harald Welte96a33b02018-02-04 10:36:22 +0100343 if (g_initialized == true) {
344 return;
345 }
346 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100347 g_gb[0].cfg := {
348 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200349 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200350 bvc := {
351 {
352 bvci := 196,
353 cell_id := {
354 ra_id := {
355 lai := {
356 mcc_mnc := mcc_mnc,
357 lac := 13135
358 },
359 rac := 0
360 },
361 cell_id := 20960
362 },
Harald Welte4d112c92020-11-12 19:48:31 +0100363 depth := BSSGP_DECODE_DEPTH_L3,
364 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200365 }
366 }
Harald Welte5ac31492018-02-15 20:39:13 +0100367 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200368 g_gb[1].cfg := {
369 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200370 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200371 bvc := {
372 {
373 bvci := 210,
374 cell_id := {
375 ra_id := {
376 lai := {
377 mcc_mnc := mcc_mnc,
378 lac := 13200
379 },
380 rac := 0
381 },
382 cell_id := 20961
383 },
Harald Welte4d112c92020-11-12 19:48:31 +0100384 depth := BSSGP_DECODE_DEPTH_L3,
385 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200386 }
387 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200388 };
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100389 g_gb[2].cfg := { /* [2] configured to have same RAC as [1] */
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200390 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200391 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200392 bvc := {
393 {
394 bvci := 220,
395 cell_id := {
396 ra_id := {
397 lai := {
398 mcc_mnc := mcc_mnc,
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100399 lac := 13200
Harald Welte5339b2e2020-10-04 22:52:56 +0200400 },
401 rac := 0
402 },
403 cell_id := 20962
404 },
Harald Welte4d112c92020-11-12 19:48:31 +0100405 depth := BSSGP_DECODE_DEPTH_L3,
406 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200407 }
408 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200409 };
Harald Welte96a33b02018-02-04 10:36:22 +0100410
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200411 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200412 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
413 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
414 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200415
Alexander Couzens1552e792019-07-23 20:38:39 +0200416 if (g_ranap_enable) {
417 for (i := 0; i < NUM_RNC; i := i+1) {
418 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
419 f_ran_adapter_start(g_ranap[i]);
420 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200421 }
Harald Welte5ac31492018-02-15 20:39:13 +0100422 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100423 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200424 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100425}
Harald Welte96a33b02018-02-04 10:36:22 +0100426
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200427function f_cleanup() runs on test_CT {
428 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200429 if (g_ranap_enable) {
430 for (i := 0; i < NUM_RNC; i := i+1) {
431 f_ran_adapter_cleanup(g_ranap[i]);
432 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200433 }
434 self.stop;
435}
436
Harald Welte26fbb6e2019-04-14 17:32:46 +0200437private function RncUnitdataCallback(RANAP_PDU ranap)
438runs on RAN_Emulation_CT return template RANAP_PDU {
439 var template RANAP_PDU resp := omit;
440
441 log ("RANAP_RncUnitDataCallback");
442 /* answer all RESET with RESET ACK */
443 if (match(ranap, tr_RANAP_Reset)) {
444 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
445 var CN_DomainIndicator dom;
446 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
447 resp := ts_RANAP_ResetAck(dom);
448 }
449 return resp;
450}
451
452const RanOps RNC_RanOps := {
453 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
454 ranap_unitdata_cb := refers(RncUnitdataCallback),
455 ps_domain := true,
456 decode_dtap := true,
457 role_ms := true,
458 protocol := RAN_PROTOCOL_RANAP,
459 transport := RANAP_TRANSPORT_IuCS,
460 use_osmux := false,
Eric Wild6e511ce2022-04-02 21:35:56 +0200461 bssap_reset_retries := 1,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200462 sccp_addr_local := omit,
463 sccp_addr_peer := omit
464};
465
Harald Welte5ac31492018-02-15 20:39:13 +0100466type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
467
468/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200469function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100470 float t_guard := 30.0, boolean expect_ciph := false)
Harald Welte5ac31492018-02-15 20:39:13 +0100471runs on test_CT return BSSGP_ConnHdlr {
472 var BSSGP_ConnHdlr vc_conn;
473 var SGSN_ConnHdlrNetworkPars net_pars := {
474 expect_ptmsi := true,
475 expect_auth := true,
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100476 expect_ciph := expect_ciph
Harald Welte5ac31492018-02-15 20:39:13 +0100477 };
478 var BSSGP_ConnHdlrPars pars := {
479 imei := f_gen_imei(imsi_suffix),
480 imsi := f_gen_imsi(imsi_suffix),
481 msisdn := f_gen_msisdn(imsi_suffix),
482 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100483 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100484 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100485 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100486 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200487 bssgp_cell_id := {
488 gb[0].cfg.bvc[0].cell_id,
489 gb[1].cfg.bvc[0].cell_id,
490 gb[2].cfg.bvc[0].cell_id
491 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200492 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100493 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100494 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200495 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200496 sccp_addr_local := omit,
497 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100498 };
499
Alexander Couzens1552e792019-07-23 20:38:39 +0200500 if (g_ranap_enable) {
501 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
502 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
503 }
504
Harald Welte5ac31492018-02-15 20:39:13 +0100505 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200506
507 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
508 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
509 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100510 connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200511
512 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
513 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
514 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100515 connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200516
517 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
518 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
519 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100520 connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL);
Harald Welte5ac31492018-02-15 20:39:13 +0100521
Harald Welte26fbb6e2019-04-14 17:32:46 +0200522 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200523 if (g_ranap_enable) {
524 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
525 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
526 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200527
Harald Welte5ac31492018-02-15 20:39:13 +0100528 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
529 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
530
Harald Welteeded9ad2018-02-17 20:57:34 +0100531 connect(vc_conn:GTP, vc_GTP:CLIENT);
532 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
533
Harald Welte5ac31492018-02-15 20:39:13 +0100534 vc_conn.start(f_handler_init(fn, id, pars));
535 return vc_conn;
536}
537
Harald Welte62e29582018-02-16 21:17:11 +0100538private altstep as_Tguard() runs on BSSGP_ConnHdlr {
539 [] g_Tguard.timeout {
540 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200541 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100542 }
543}
544
Harald Welte5ac31492018-02-15 20:39:13 +0100545/* first function called in every ConnHdlr */
546private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
547runs on BSSGP_ConnHdlr {
548 /* do some common stuff like setting up g_pars */
549 g_pars := pars;
550
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200551 llc := f_llc_create(false);
552
Harald Welte5ac31492018-02-15 20:39:13 +0100553 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200554 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100555 /* tell GSUP dispatcher to send this IMSI to us */
556 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100557 /* tell GTP dispatcher to send this IMSI to us */
558 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100559
Harald Welte62e29582018-02-16 21:17:11 +0100560 g_Tguard.start(pars.t_guard);
561 activate(as_Tguard());
562
Harald Welte5ac31492018-02-15 20:39:13 +0100563 /* call the user-supplied test case function */
564 fn.apply(id);
565 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100566}
567
568/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100569 * Detach without Attach
570 * SM procedures without attach / RAU
571 * ATTACH / RAU
572 ** with / without authentication
573 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100574 * re-transmissions of LLC frames
575 * PDP Context activation
576 ** with different GGSN config in SGSN VTY
577 ** with different PDP context type (v4/v6/v46)
578 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100579 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100580 */
581
582testcase TC_wait_ns_up() runs on test_CT {
583 f_init();
584 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200585 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100586}
587
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200588friend function is_gb(integer ran_index) return boolean {
589 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200590}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200591friend function is_iu(integer ran_index) return boolean {
592 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200593}
594
Alexander Couzens0507ec32019-09-15 22:41:22 +0200595function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200596 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200597 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 +0200598}
599
Alexander Couzens0507ec32019-09-15 22:41:22 +0200600private 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 +0200601 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
602 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
603 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200604 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200605}
606
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200607/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
608function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
609 log("Sending InitialUE: ", l3_mo);
610 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
611 var RANAP_PDU ranap;
612 var LAI lai := {
613 pLMNidentity := '62F224'O,
614 lAC := '1234'O,
615 iE_Extensions := omit
616 };
617 var SAI sai := {
618 pLMNidentity := lai.pLMNidentity,
619 lAC := lai.lAC,
620 sAC := '0000'O, /* FIXME */
621 iE_Extensions := omit
622 };
623 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
624 var GlobalRNC_ID grnc_id := {
625 pLMNidentity := lai.pLMNidentity,
626 rNC_ID := 2342 /* FIXME */
627 };
628
629 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
630 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
631 alt {
632 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
633 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
634 setverdict(fail, "DISC.ind from SCCP");
635 mtc.stop;
636 }
637 }
638}
639
640/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200641function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
642 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200643 if (g_pars.rnc_send_initial_ue) {
644 g_pars.rnc_send_initial_ue := false;
645 f_send_l3_initial_ue(l3_mo);
646 } else {
647 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
648 }
649 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200650 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200651 }
652}
653
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200654altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700655 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200656 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100657 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200658 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100659 repeat;
660 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200661 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200662 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200663 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200664 repeat;
665 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200666 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100667 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200668 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200669 repeat;
670 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200671 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200672 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200673 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100674 repeat;
675 }
676}
Harald Welte96a33b02018-02-04 10:36:22 +0100677
Harald Welteca362462019-05-02 20:11:21 +0200678/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200679function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200680runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200681 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200682 var PDU_L3_SGSN_MS l3_mt;
683 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200684 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
685 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200686 l3_mt := mt.dtap;
687 }
Harald Welteca362462019-05-02 20:11:21 +0200688 }
689 return l3_mt;
690}
691
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100692/* (copied from msc/BSC_ConnectionHandler.ttcn) */
693private altstep as_ciph_utran() runs on BSSGP_ConnHdlr
694{
695 [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(uia_algs := ?,
696 uia_key := oct2bit(g_pars.vec.ik),
697 key_sts := ?,
698 uea_algs := ?,
699 uea_key := oct2bit(g_pars.vec.ck))) {
700 var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1*/
701 var EncryptionAlgorithm uea_chosen := 1; /*standard_UMTS_encryption_algorith_UEA1*/
702 BSSAP.send(ts_RANAP_SecurityModeCompleteEnc(uia_chosen, uea_chosen));
703 }
704 [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(?,?,?,?,?)) {
705 setverdict(fail, "Invalid SecurityModeCommand (ciphering case)");
706 mtc.stop;
707 }
708 [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?,
709 uia_key := oct2bit(g_pars.vec.ik),
710 key_sts := ?)) {
711 var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1;*/
712 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
713 }
714 [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(?,?,?)) {
715 setverdict(fail, "Invalid SecurityModeCommand (non-ciphering case)");
716 mtc.stop;
717 }
718}
719
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200720/* perform GMM authentication (if expected).
721 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
722 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200723function 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 +0100724 var PDU_L3_MS_SGSN l3_mo;
725 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200726 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100727 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200728 var GSUP_IE auth_tuple;
729 var template AuthenticationParameterAUTNTLV autn;
730
731 if (umts_aka_challenge) {
732 g_pars.vec := f_gen_auth_vec_3g();
733 autn := {
734 elementIdentifier := '28'O,
735 lengthIndicator := lengthof(g_pars.vec.autn),
736 autnValue := g_pars.vec.autn
737 };
738
739 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
740 g_pars.vec.sres,
741 g_pars.vec.kc,
742 g_pars.vec.ik,
743 g_pars.vec.ck,
744 g_pars.vec.autn,
745 g_pars.vec.res));
746 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
747 } else {
748 g_pars.vec := f_gen_auth_vec_2g();
749 autn := omit;
750 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
751 g_pars.vec.sres,
752 g_pars.vec.kc));
753 log("GSUP sends only 2G auth tuple", auth_tuple);
754 }
Harald Welteca362462019-05-02 20:11:21 +0200755
Harald Welte5ac31492018-02-15 20:39:13 +0100756 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
757 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200758
759 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
760 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200761 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100762 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +0700763 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 +0200764
765 if (umts_aka_challenge and not force_gsm_sres) {
766 /* set UMTS response instead */
767 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
768 valueField := substr(g_pars.vec.res, 0, 4)
769 };
770 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
771 elementIdentifier := '21'O,
772 lengthIndicator := lengthof(g_pars.vec.res) - 4,
773 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
774 };
775 }
776
777 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100778 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
779 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
780 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
781 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
782 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200783 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200784
785 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200786 if (is_iu(ran_index)) {
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100787 as_ciph_utran();
788 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200789 }
Harald Welte76dee092018-02-16 22:12:59 +0100790 } else {
791 /* wait for identity procedure */
792 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100793 }
Harald Welte76dee092018-02-16 22:12:59 +0100794
Harald Welte5ac31492018-02-15 20:39:13 +0100795 deactivate(di);
796}
797
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200798function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100799 g_pars.p_tmsi := p_tmsi;
800 /* update TLLI */
801 g_pars.tlli_old := g_pars.tlli;
802 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100803 if (is_gb(ran_index)) {
804 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
805 }
Harald Weltef70997d2018-02-17 10:11:19 +0100806}
807
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100808function f_process_attach_accept(PDU_GMM_AttachAccept aa, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100809 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100810 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Harald Weltedd9fb842021-02-16 20:21:22 +0100811 /* we cannot use ran_index here, as it would overflow the cell_id object, since ran_idx > NUM_GB
812 * indicates an Iu RAN connection. All cells are expected to run the same MCC/MNC anyway... */
813 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100814 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100815 & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200816 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100817 }
Harald Welte04683d02018-02-16 22:43:45 +0100818 g_pars.ra := aa.routingAreaIdentification;
819 if (ispresent(aa.allocatedPTMSI)) {
820 if (not g_pars.net.expect_ptmsi) {
821 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200822 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100823 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100824 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
825 ran_index);
Harald Welte04683d02018-02-16 22:43:45 +0100826 }
827 if (ispresent(aa.msIdentity)) {
828 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200829 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100830 }
831 /* P-TMSI.sig */
832 if (ispresent(aa.ptmsiSignature)) {
833 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
834 }
835 /* updateTimer */
836 // aa.readyTimer
837 /* T3302, T3319, T3323, T3312_ext, T3324 */
838}
839
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200840function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100841 /* mandatory IE */
842 g_pars.ra := ra.routingAreaId;
843 if (ispresent(ra.allocatedPTMSI)) {
844 if (not g_pars.net.expect_ptmsi) {
845 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200846 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100847 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100848 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
849 ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100850 }
851 if (ispresent(ra.msIdentity)) {
852 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200853 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100854 }
855 /* P-TMSI.sig */
856 if (ispresent(ra.ptmsiSignature)) {
857 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
858 }
859 /* updateTimer */
860 // aa.readyTimer
861 /* T3302, T3319, T3323, T3312_ext, T3324 */
862}
863
864
Harald Welte5a4fa042018-02-16 20:59:21 +0100865function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
866 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
867}
868
Harald Welte23178c52018-02-17 09:36:33 +0100869/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700870private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100871 if (ispresent(g_pars.p_tmsi)) {
872 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
873 } else {
874 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
875 }
876}
877
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700878private altstep as_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
879 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
880 var GSUP_PDU gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
Pau Espin Pedrolc63fa8e2024-01-22 19:58:09 +0100881 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo('00'O, char2oct("*"), ts_EuaIPv4Dyn, ''O)) };
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700882 GSUP.send(gsup);
883 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
884 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
885 }
Harald Welte311ec272018-02-17 09:40:03 +0100886}
887
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100888friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0,
889 template (omit) RoutingAreaIdentificationV old_ra := omit) runs on BSSGP_ConnHdlr {
890 var RoutingAreaIdentificationV old_ra_val;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +0700891 var template (value) PDU_L3_MS_SGSN attach_req;
Harald Welteca362462019-05-02 20:11:21 +0200892 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100893
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100894 if (istemplatekind(old_ra, "omit")) {
895 old_ra_val := f_random_RAI();
896 } else {
897 old_ra_val := valueof(old_ra);
898 }
899
900 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra_val, false, false, omit, omit);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200901 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
902 * 3G auth vectors */
903 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
904 /* The thing is, if the solSACapability is 'omit', then the
905 * revisionLevelIndicatior is at the wrong place! */
906 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
907
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200908 f_send_l3(attach_req, ran_index);
909 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200910 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700911 as_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100912
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200913 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100914 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200915
Harald Welte04683d02018-02-16 22:43:45 +0100916 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200917 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200918
919 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200920 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200921 as_iu_release_compl_disc();
922 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200923
924 /* Race condition
925 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
926 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
927 * arrived before it. This results in a test case failure.
928 * Delay execution by 50 ms
929 */
930 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200931}
932
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200933friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
934 timer T := 5.0;
935 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100936 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 +0200937 T.start;
938 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100939 [] 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 +0200940 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
941 }
Harald Welte9b461a92020-12-10 23:41:14 +0100942 [] 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 +0200943 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
944 mtc.stop;
945 }
946 [] T.timeout {
947 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
948 mtc.stop;
949 }
950 }
951 return '00'O;
952}
953
954friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
955 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100956 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 +0200957 T.start;
958 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100959 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
960 [] 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 +0200961?)) {
962 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
963 mtc.stop;
964 }
965 [] T.timeout {
966 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
967 mtc.stop;
968 }
969 }
970}
971
972
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200973private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
974 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100975 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100976}
977
978testcase TC_attach() runs on test_CT {
979 var BSSGP_ConnHdlr vc_conn;
980 f_init();
981 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200982 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100983 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200984 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100985}
986
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100987testcase TC_attach_mnc3() runs on test_CT {
988 var BSSGP_ConnHdlr vc_conn;
989 f_init('023042'H);
990 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200991 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100992 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200993 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100994}
995
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200996private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
997 f_gmm_attach(true, false);
998 setverdict(pass);
999}
1000testcase TC_attach_umts_aka_umts_res() runs on test_CT {
1001 var BSSGP_ConnHdlr vc_conn;
1002 f_init();
1003 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001004 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001005 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001006 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001007}
1008
1009private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
1010 f_gmm_attach(true, true);
1011 setverdict(pass);
1012}
1013testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
1014 var BSSGP_ConnHdlr vc_conn;
1015 f_init();
1016 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001017 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001018 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001019 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001020}
1021
arehbein3ede9e32023-02-06 21:02:53 +01001022/* Let T3350 expire while the MS holds an active PDP context (OS#4221). Do this by
1023 * Establishing a PDP context and then resending an ATTACH REQUEST,
1024 * making sure that exactly five ATTACH ACCEPTS are sent */
1025private function f_TC_attach_timeout_after_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
1026 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1027 /* Vars needed for triggering T3350 timeouts */
1028 const integer ran_index := 0;
1029 /* See TS 24.008 Rel. 16 Sect. 4.7.3.1.6 c) */
1030 const integer gmm_attach_repeats := 5;
1031 /* See TS 24.008 Rel. 16 Table 11.4 */
1032 const float T3350 := 6.0;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07001033 var template (value) PDU_L3_MS_SGSN attach_req;
arehbein3ede9e32023-02-06 21:02:53 +01001034 timer t_receive_GMM_ATTACH_ACCEPT;
1035 var RoutingAreaIdentificationV rai := f_random_RAI();
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001036 timer T;
arehbein3ede9e32023-02-06 21:02:53 +01001037
1038 /* First establish PDP context */
1039 f_TC_attach(id);
1040 f_pdp_ctx_act(apars);
1041
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001042 /* Now, try another GPRS attach procedure. Note that osmo-sgsn does not require
1043 * authentication for the second GMM ATTACH REQUEST, so we expect GSUP UPDATE
1044 * LOCATION REQUEST and optionally a GMM IDENTITY REQUEST (IMEI). */
arehbein3ede9e32023-02-06 21:02:53 +01001045 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), rai, false, false, omit, omit);
1046 f_send_l3(attach_req, ran_index);
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001047
1048 T.start(1.0);
1049 alt {
1050 [] as_gmm_gsup_lu_isd();
1051 [] as_mm_identity(ran_index);
1052 [] as_xid(apars, ran_index);
1053 [] T.timeout {
1054 setverdict(fail, "Timeout waiting for GSUP UPDATE LOCATION REQUEST");
1055 return;
1056 }
1057 }
arehbein3ede9e32023-02-06 21:02:53 +01001058
1059 BSSGP[ran_index].clear;
1060 log("Trying to receive ", gmm_attach_repeats, " ATTACH ACCEPTs");
1061 for (var integer i := 1; i <= gmm_attach_repeats; i := i+1) {
1062 t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5);
1063 alt {
1064 [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) {
1065 t_receive_GMM_ATTACH_ACCEPT.stop;
1066 }
1067 [] t_receive_GMM_ATTACH_ACCEPT.timeout {
1068 setverdict(fail, "Timeout on receiving ", i, "th ATTACH ACCEPT")
1069 }
1070 }
1071 }
1072 log("Have received ", gmm_attach_repeats, " ATTACH ACCEPT messages");
1073 log("Make sure not more than ", gmm_attach_repeats, " ATTACH ACCEPT messages are sent");
1074 t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5);
1075 alt {
1076 [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) {
1077 setverdict(fail, "Received ", gmm_attach_repeats + 1, "th ATTACH ACCEPT")
1078 }
1079 [] t_receive_GMM_ATTACH_ACCEPT.timeout { }
1080 }
1081
1082 setverdict(pass);
1083}
1084
1085testcase TC_attach_timeout_after_pdp_act() runs on test_CT {
1086 var BSSGP_ConnHdlr vc_conn;
1087 f_init();
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001088 vc_conn := f_start_handler(refers(f_TC_attach_timeout_after_pdp_act),
1089 testcasename(), g_gb, 21, t_guard := 45.0);
1090 vc_conn.done;
arehbein3ede9e32023-02-06 21:02:53 +01001091 f_cleanup();
1092}
1093
Harald Welte5b7c8122018-02-16 21:48:17 +01001094/* MS never responds to ID REQ, expect ATTACH REJECT */
1095private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001096 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1097
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001098 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001099 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001100 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001101 /* don't send ID Response */
1102 repeat;
1103 }
Harald Welte955aa942019-05-03 01:29:29 +02001104 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001105 setverdict(pass);
1106 }
Harald Welte955aa942019-05-03 01:29:29 +02001107 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001108 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +02001109 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001110 }
1111 }
1112}
1113testcase TC_attach_auth_id_timeout() runs on test_CT {
1114 var BSSGP_ConnHdlr vc_conn;
1115 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001116 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 +01001117 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001118 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001119}
1120
1121/* HLR never responds to SAI REQ, expect ATTACH REJECT */
1122private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001123 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1124
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001125 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001126 alt {
1127 [] as_mm_identity();
1128 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1129 }
1130 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001131 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001132 setverdict(pass);
1133}
1134testcase TC_attach_auth_sai_timeout() runs on test_CT {
1135 var BSSGP_ConnHdlr vc_conn;
1136 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001137 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001138 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001139 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001140}
1141
Harald Weltefe253882018-02-17 09:25:00 +01001142/* HLR rejects SAI, expect ATTACH REJECT */
1143private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001144 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1145
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001146 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001147 alt {
1148 [] as_mm_identity();
1149 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1150 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1151 }
1152 }
Harald Welte955aa942019-05-03 01:29:29 +02001153 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001154 setverdict(pass);
1155}
1156testcase TC_attach_auth_sai_reject() runs on test_CT {
1157 var BSSGP_ConnHdlr vc_conn;
1158 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001159 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001160 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001161 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001162}
1163
Harald Welte5b7c8122018-02-16 21:48:17 +01001164/* HLR never responds to UL REQ, expect ATTACH REJECT */
1165private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001166 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001167 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1168
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001169 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001170 f_gmm_auth();
1171 /* Expect MSC to perform LU with HLR */
1172 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1173 /* Never follow-up with ISD_REQ or UL_RES */
1174 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001175 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001176 setverdict(pass);
1177 }
Harald Welte955aa942019-05-03 01:29:29 +02001178 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1179 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001180 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001181 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001182 }
1183 }
1184}
1185testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1186 var BSSGP_ConnHdlr vc_conn;
1187 f_init();
1188 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001189 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001190 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001191 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001192}
1193
Harald Welteb7c14e92018-02-17 09:29:16 +01001194/* HLR rejects UL REQ, expect ATTACH REJECT */
1195private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001196 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001197 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1198
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001199 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001200 f_gmm_auth();
1201 /* Expect MSC to perform LU with HLR */
1202 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1203 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1204 }
1205 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001206 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001207 setverdict(pass);
1208 }
Harald Welte955aa942019-05-03 01:29:29 +02001209 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1210 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001211 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001212 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001213 }
1214 }
1215}
1216testcase TC_attach_gsup_lu_reject() runs on test_CT {
1217 var BSSGP_ConnHdlr vc_conn;
1218 f_init();
1219 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001220 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001221 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001222 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001223}
1224
1225
Harald Welte3823e2e2018-02-16 21:53:48 +01001226/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1227private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001228 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001229 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1230
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001231 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001232 f_gmm_auth();
1233 /* Expect MSC to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07001234 as_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001235
Harald Welte955aa942019-05-03 01:29:29 +02001236 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1237 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001238 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001239 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001240 setverdict(pass);
1241}
Harald Welte3823e2e2018-02-16 21:53:48 +01001242testcase TC_attach_combined() runs on test_CT {
1243 var BSSGP_ConnHdlr vc_conn;
1244 f_init();
1245 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001246 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001247 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001248 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001249}
1250
Harald Welte76dee092018-02-16 22:12:59 +01001251/* Attempt of GPRS ATTACH in 'accept all' mode */
1252private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001253 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001254 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1255
1256 g_pars.net.expect_auth := false;
1257
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001258 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001259 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001260 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1261 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001262 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001263 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001264 setverdict(pass);
1265}
1266testcase TC_attach_accept_all() runs on test_CT {
1267 var BSSGP_ConnHdlr vc_conn;
1268 f_init();
1269 f_sleep(1.0);
1270 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001271 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001272 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001273 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001274}
Harald Welte5b7c8122018-02-16 21:48:17 +01001275
Harald Welteb2124b22018-02-16 22:26:56 +01001276/* Attempt of GPRS ATTACH in 'accept all' mode */
1277private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001278 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1279
1280 /* Simulate a foreign IMSI */
1281 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001282 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001283
1284 g_pars.net.expect_auth := false;
1285
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001286 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001287 alt {
1288 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001289 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001290 setverdict(pass);
1291 }
Harald Welte955aa942019-05-03 01:29:29 +02001292 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001293 setverdict(pass);
1294 }
Harald Welte955aa942019-05-03 01:29:29 +02001295 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001296 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001297 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001298 }
Harald Welteb2124b22018-02-16 22:26:56 +01001299 }
1300}
1301testcase TC_attach_closed() runs on test_CT {
1302 var BSSGP_ConnHdlr vc_conn;
1303 f_init();
1304 f_sleep(1.0);
1305 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1306 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001307 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001308 vc_conn.done;
1309 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001310 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001311 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001312 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001313}
1314
Harald Welte04683d02018-02-16 22:43:45 +01001315/* Routing Area Update from Unknown TLLI -> REJECT */
1316private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001317 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1318
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001319 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 +01001320 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001321 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001322 setverdict(pass);
1323 }
1324 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001325 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001326 }
1327}
1328testcase TC_rau_unknown() runs on test_CT {
1329 var BSSGP_ConnHdlr vc_conn;
1330 f_init();
1331 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001332 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001333 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001334 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001335}
1336
Harald Welte91636de2018-02-17 10:16:14 +01001337private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001338 /* first perform regular attach */
1339 f_TC_attach(id);
1340
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001341 f_routing_area_update(g_pars.ra);
1342
Harald Welte91636de2018-02-17 10:16:14 +01001343}
1344testcase TC_attach_rau() runs on test_CT {
1345 var BSSGP_ConnHdlr vc_conn;
1346 f_init();
1347 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001348 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001349 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001350 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001351}
Harald Welte04683d02018-02-16 22:43:45 +01001352
Harald Welte6abb9fe2018-02-17 15:24:48 +01001353/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001354function 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 +02001355 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001356 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001357 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001358 if (expect_purge) {
1359 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1360 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1361 }
1362 T.start;
1363 alt {
1364 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1365 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001366 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001367 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001368 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001369 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001370 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001371 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001372 /* TODO: check if any PDP contexts are deactivated on network side? */
1373 }
1374 [power_off] T.timeout {
1375 setverdict(pass);
1376 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001377 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001378 g_pars.ra := omit;
1379 setverdict(pass);
1380 /* TODO: check if any PDP contexts are deactivated on network side? */
1381 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001382 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001383 if (power_off) {
1384 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1385 } else {
1386 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1387 }
1388 mtc.stop;
1389 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001390 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001391 }
1392}
1393
1394/* IMSI DETACH (non-power-off) for unknown TLLI */
1395private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1396 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1397}
1398testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1399 var BSSGP_ConnHdlr vc_conn;
1400 f_init();
1401 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001402 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001403 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001404 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001405}
1406
1407/* IMSI DETACH (power-off) for unknown TLLI */
1408private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1409 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1410}
1411testcase TC_detach_unknown_poweroff() runs on test_CT {
1412 var BSSGP_ConnHdlr vc_conn;
1413 f_init();
1414 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001415 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001416 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001417 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001418}
1419
1420/* IMSI DETACH (non-power-off) for known TLLI */
1421private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1422 /* first perform regular attach */
1423 f_TC_attach(id);
1424
1425 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1426}
1427testcase TC_detach_nopoweroff() runs on test_CT {
1428 var BSSGP_ConnHdlr vc_conn;
1429 f_init();
1430 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001431 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001432 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001433 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001434}
1435
1436/* IMSI DETACH (power-off) for known TLLI */
1437private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1438 /* first perform regular attach */
1439 f_TC_attach(id);
1440
1441 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1442}
1443testcase TC_detach_poweroff() runs on test_CT {
1444 var BSSGP_ConnHdlr vc_conn;
1445 f_init();
1446 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001447 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001448 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001449 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001450}
1451
Harald Welteeded9ad2018-02-17 20:57:34 +01001452type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001453 BIT3 tid, /* L3 Transaction ID */
1454 BIT4 nsapi, /* SNDCP NSAPI */
1455 BIT4 sapi, /* LLC SAPI */
1456 QoSV qos, /* QoS parameters */
1457 PDPAddressV addr, /* IP address */
1458 octetstring apn optional, /* APN name */
1459 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1460 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001461 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001462 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001463
Harald Welte822f9102018-02-18 20:39:06 +01001464 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1465 OCT4 ggsn_tei_u, /* GGSN TEI User */
1466 octetstring ggsn_ip_c, /* GGSN IP Control */
1467 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001468 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001469
Harald Welte822f9102018-02-18 20:39:06 +01001470 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1471 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1472 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1473 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001474};
1475
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001476
1477private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1478 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1479 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1480 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1481 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1482 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1483 f_gtp_register_teid(apars.ggsn_tei_c);
1484 f_gtp_register_teid(apars.ggsn_tei_u);
1485}
1486
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001487function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001488runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001489 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1490 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001491 var template Recovery_gtpc recovery := omit;
1492
1493 if (send_recovery) {
1494 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1495 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001496
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001497 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 +02001498 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001499 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1500 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1501 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1502 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1503 apars.sgsn_tei_c, apars.gtp_resp_cause,
1504 apars.ggsn_tei_c, apars.ggsn_tei_u,
1505 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001506 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1507 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001508 }
1509 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001510 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001511 setverdict(pass);
1512 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001513 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001514 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001515 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001516 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001517 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001518 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001519 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001520 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001521 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001522 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1523 mtc.stop;
1524 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001525 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001526 setverdict(pass);
1527 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001528 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001529 }
1530}
1531
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001532function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001533runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001534 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1535 var Gtp1cUnitdata g_ud;
1536
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001537 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001538 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1539 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001540 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001541 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1542 }
1543 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001544 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001545 setverdict(pass);
1546 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001547 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001548 }
1549}
1550
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001551function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001552runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001553 var Gtp1cUnitdata g_ud;
1554 var integer seq_nr := 23;
Harald Welte57b9b7f2018-02-18 22:28:13 +01001555
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001556 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001557 if (error_ind) {
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001558 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_c));
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001559 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1560 } else {
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001561 var Gtp1cPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001562 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1563 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001564
1565 timer T := 5.0;
1566 T.start;
1567
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001568 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001569 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1570 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001571 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001572 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1573 repeat;
1574 }
1575 [] T.timeout {
1576 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1577 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001578 }
1579}
1580
Harald Welte6f203162018-02-18 22:04:55 +01001581
Harald Welteeded9ad2018-02-17 20:57:34 +01001582/* Table 10.5.156/3GPP TS 24.008 */
1583template (value) QoSV t_QosDefault := {
1584 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1585 delayClass := '100'B, /* best effort */
1586 spare1 := '00'B,
1587 precedenceClass := '010'B, /* normal */
1588 spare2 := '0'B,
1589 peakThroughput := '0000'B, /* subscribed */
1590 meanThroughput := '00000'B, /* subscribed */
1591 spare3 := '000'B,
1592 deliverErroneusSDU := omit,
1593 deliveryOrder := omit,
1594 trafficClass := omit,
1595 maxSDUSize := omit,
1596 maxBitrateUplink := omit,
1597 maxBitrateDownlink := omit,
1598 sduErrorRatio := omit,
1599 residualBER := omit,
1600 trafficHandlingPriority := omit,
1601 transferDelay := omit,
1602 guaranteedBitRateUplink := omit,
1603 guaranteedBitRateDownlink := omit,
1604 sourceStatisticsDescriptor := omit,
1605 signallingIndication := omit,
1606 spare4 := omit,
1607 maxBitrateDownlinkExt := omit,
1608 guaranteedBitRateDownlinkExt := omit,
1609 maxBitrateUplinkExt := omit,
1610 guaranteedBitRateUplinkExt := omit,
1611 maxBitrateDownlinkExt2 := omit,
1612 guaranteedBitRateDownlinkExt2 := omit,
1613 maxBitrateUplinkExt2 := omit,
1614 guaranteedBitRateUplinkExt2 := omit
1615}
1616
1617/* 10.5.6.4 / 3GPP TS 24.008 */
1618template (value) PDPAddressV t_AddrIPv4dyn := {
1619 pdpTypeOrg := '0001'B, /* IETF */
1620 spare := '0000'B,
1621 pdpTypeNum := '21'O, /* IPv4 */
1622 addressInfo := omit
1623}
1624template (value) PDPAddressV t_AddrIPv6dyn := {
1625 pdpTypeOrg := '0001'B, /* IETF */
1626 spare := '0000'B,
1627 pdpTypeNum := '53'O, /* IPv6 */
1628 addressInfo := omit
1629}
1630
Harald Welte37692d82018-02-18 15:21:34 +01001631template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001632 tid := '000'B,
1633 nsapi := '0101'B, /* < 5 are reserved */
1634 sapi := '0011'B, /* 3/5/9/11 */
1635 qos := t_QosDefault,
1636 addr := t_AddrIPv4dyn,
1637 apn := omit,
1638 pco := omit,
1639 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001640 gtp_resp_cause := int2oct(128, 1),
1641 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001642
1643 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001644 ggsn_tei_c := f_rnd_octstring(4),
1645 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001646 ggsn_ip_c := f_inet_addr(ggsn_ip),
1647 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001648 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001649
Harald Welteeded9ad2018-02-17 20:57:34 +01001650 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001651 sgsn_tei_u := omit,
1652 sgsn_ip_c := omit,
1653 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001654}
1655
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001656template (value) Gtp1uPeer ts_GtpPeerU(octetstring ip) := {
Harald Welte37692d82018-02-18 15:21:34 +01001657 connId := 1,
1658 remName := f_inet_ntoa(ip),
1659 remPort := GTP1U_PORT
1660}
1661
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001662template (value) Gtp1cPeer ts_GtpPeerC(octetstring ip) := {
Harald Welte37692d82018-02-18 15:21:34 +01001663 connId := 1,
1664 remName := f_inet_ntoa(ip),
1665 remPort := GTP1C_PORT
1666}
1667
1668private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001669 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
Harald Welte37692d82018-02-18 15:21:34 +01001670 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1671}
1672
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001673private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1674 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001675 repeat;
1676 }
1677}
1678
1679template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1680 pDU_SN_UNITDATA := {
1681 nsapi := nsapi,
1682 moreBit := ?,
1683 snPduType := '1'B,
1684 firstSegmentIndicator := ?,
1685 spareBit := ?,
1686 pcomp := ?,
1687 dcomp := ?,
1688 npduNumber := ?,
1689 segmentNumber := ?,
1690 npduNumberContinued := ?,
1691 dataSegmentSnUnitdataPdu := payload
1692 }
1693}
1694
1695/* simple case: single segment, no compression */
1696template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1697 pDU_SN_UNITDATA := {
1698 nsapi := nsapi,
1699 moreBit := '0'B,
1700 snPduType := '1'B,
1701 firstSegmentIndicator := '1'B,
1702 spareBit := '0'B,
1703 pcomp := '0000'B,
1704 dcomp := '0000'B,
1705 npduNumber := '0000'B,
1706 segmentNumber := '0000'B,
1707 npduNumberContinued := '00'O,
1708 dataSegmentSnUnitdataPdu := payload
1709 }
1710}
1711
1712/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001713private 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 +02001714runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001715 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001716 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1717 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001718 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001719 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1720 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001721 [] as_xid(apars, ran_index);
1722 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001723 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1724 [expect_fwd] T.timeout {
1725 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1726 mtc.stop;
1727 }
1728 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1729 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1730 mtc.stop;
1731 }
1732 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001733 }
1734}
1735
Harald Welte64d6b512020-06-17 16:42:00 +02001736/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001737private 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 +02001738runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001739 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001740 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
Harald Welte37692d82018-02-18 15:21:34 +01001741 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001742 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, n_u));
Harald Welte37692d82018-02-18 15:21:34 +01001743 /* Expect PDU via GTP from SGSN on simulated GGSN */
1744 alt {
1745 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1746 }
1747}
1748
Harald Welteeded9ad2018-02-17 20:57:34 +01001749private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001750 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001751
1752 /* first perform regular attach */
1753 f_TC_attach(id);
1754
1755 f_pdp_ctx_act(apars);
1756}
1757testcase TC_attach_pdp_act() runs on test_CT {
1758 var BSSGP_ConnHdlr vc_conn;
1759 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001760 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001761 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001762 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001763}
Harald Welteb2124b22018-02-16 22:26:56 +01001764
Harald Welte835b15f2018-02-18 14:39:11 +01001765/* PDP Context activation for not-attached subscriber; expect fail */
1766private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001767 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001768 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 +01001769 apars.apn, apars.pco));
1770 alt {
1771 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001772 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001773 setverdict(pass);
1774 }
1775 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1776 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001777 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001778 }
Harald Welte955aa942019-05-03 01:29:29 +02001779 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001780 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001781 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001782 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001783 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001784 }
1785}
1786testcase TC_pdp_act_unattached() runs on test_CT {
1787 var BSSGP_ConnHdlr vc_conn;
1788 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001789 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001790 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001791 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001792}
1793
Harald Welte37692d82018-02-18 15:21:34 +01001794/* ATTACH + PDP CTX ACT + user plane traffic */
1795private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1796 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1797
1798 /* first perform regular attach */
1799 f_TC_attach(id);
1800 /* then activate PDP context */
1801 f_pdp_ctx_act(apars);
1802 /* then transceive a downlink PDU */
1803 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1804 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1805}
1806testcase TC_attach_pdp_act_user() runs on test_CT {
1807 var BSSGP_ConnHdlr vc_conn;
1808 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001809 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001810 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001811 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001812}
1813
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001814/* ATTACH + PDP CTX ACT; reject from GGSN */
1815private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1816 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1817
1818 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1819 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1820
1821 /* first perform regular attach */
1822 f_TC_attach(id);
1823 /* then activate PDP context */
1824 f_pdp_ctx_act(apars);
1825}
1826testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1827 var BSSGP_ConnHdlr vc_conn;
1828 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001829 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001830 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001831 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001832}
Harald Welte835b15f2018-02-18 14:39:11 +01001833
Harald Welte6f203162018-02-18 22:04:55 +01001834/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1835private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1836 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1837
1838 /* first perform regular attach */
1839 f_TC_attach(id);
1840 /* then activate PDP context */
1841 f_pdp_ctx_act(apars);
1842 /* then transceive a downlink PDU */
1843 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1844 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1845
1846 f_pdp_ctx_deact_mo(apars, '00'O);
1847}
1848testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1849 var BSSGP_ConnHdlr vc_conn;
1850 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001851 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 +01001852 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001853 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001854}
1855
Harald Welte57b9b7f2018-02-18 22:28:13 +01001856/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1857private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1858 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1859
1860 /* first perform regular attach */
1861 f_TC_attach(id);
1862 /* then activate PDP context */
1863 f_pdp_ctx_act(apars);
1864 /* then transceive a downlink PDU */
1865 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1866 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1867
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001868 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001869}
1870testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1871 var BSSGP_ConnHdlr vc_conn;
1872 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001873 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 +01001874 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001875 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001876}
1877
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001878/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1879private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1880 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1881 var Gtp1cUnitdata g_ud;
1882 var integer i;
1883 var OCT1 cause_regular_deact := '24'O;
1884
1885 /* first perform regular attach + PDP context act */
1886 f_TC_attach(id);
1887 f_pdp_ctx_act(apars);
1888
1889 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1890 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1891
1892 for (i := 0; i < 2; i := i+1) {
1893 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1894 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1895 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1896 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1897 }
1898 }
1899
1900 alt {
1901 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1902 setverdict(pass);
1903 }
1904 [] as_xid(apars, 0);
1905 }
1906
1907 /* Make sure second DeactPdpAccept is sent: */
1908 timer T := 2.0;
1909 T.start;
1910 alt {
1911 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1912 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1913 }
1914 [] T.timeout {
1915 setverdict(pass);
1916 }
1917 }
1918
1919 setverdict(pass);
1920}
1921testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1922 var BSSGP_ConnHdlr vc_conn;
1923 f_init();
1924 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1925 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001926 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001927}
1928
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001929/* ATTACH + ATTACH (2nd) */
1930private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1931 g_pars.t_guard := 5.0;
1932
1933 /* first perform regular attach */
1934 f_TC_attach(id);
1935
1936 /* second to perform regular attach */
1937 f_TC_attach(id);
1938}
1939
1940
1941testcase TC_attach_second_attempt() runs on test_CT {
1942 var BSSGP_ConnHdlr vc_conn;
1943 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001944 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001945 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001946 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001947}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001948
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001949private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1950 var Gtp1cUnitdata g_ud;
1951 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1952 var integer seq_nr;
1953
1954 /* first perform regular attach */
1955 f_TC_attach(id);
1956 /* then activate PDP context */
1957 f_pdp_ctx_act(apars);
1958
1959 /* Wait to receive first echo request and send initial Restart counter */
1960 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1961 BSSGP[0].clear;
1962 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1963 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1964 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1965 }
1966
1967 /* At some point next echo request not answered will timeout and SGSN
1968 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1969 timer T := 3.0 * 6.0 + 16.0;
1970 T.start;
1971 alt {
1972 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1973 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1974 setverdict(pass);
1975 }
1976 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1977 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1978 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1979 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1980 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1981 repeat;
1982 }
1983 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1984 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1985 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1986 repeat;
1987 }
1988 [] T.timeout {
1989 setverdict(fail, "BSSGP DeactPdpReq not received");
1990 mtc.stop;
1991 }
1992 [] as_xid(apars);
1993 }
1994 T.stop
1995
1996 setverdict(pass);
1997}
1998/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1999testcase TC_attach_echo_timeout() runs on test_CT {
2000 var BSSGP_ConnHdlr vc_conn;
2001 g_use_echo := true;
2002 f_init();
2003 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
2004 vc_conn.done;
2005 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002006 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002007}
2008
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002009private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002010 var Gtp1cUnitdata g_ud;
2011 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2012
2013 /* first perform regular attach */
2014 f_TC_attach(id);
2015 /* Activate a pdp context against the GGSN */
2016 f_pdp_ctx_act(apars);
2017 /* Wait to receive first echo request and send initial Restart counter */
2018 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
2019 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
2020 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
2021 }
2022 /* Wait to receive second echo request and send incremented Restart
2023 counter. This will fake a restarted GGSN, and pdp ctx allocated
2024 should be released by SGSN */
2025 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
2026 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
2027 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
2028 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
2029 }
2030 var OCT1 cause_network_failure := int2oct(38, 1)
2031 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002032 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002033 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002034 setverdict(pass);
2035 }
2036 [] as_xid(apars);
2037 }
2038 setverdict(pass);
2039}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002040/* ATTACH + trigger Recovery procedure through EchoResp */
2041testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002042 var BSSGP_ConnHdlr vc_conn;
2043 g_use_echo := true
2044 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002045 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 +02002046 vc_conn.done;
2047 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002048 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002049}
2050
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002051private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
2052 var Gtp1cUnitdata g_ud;
2053 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2054 var integer seq_nr := 23;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002055 /* first perform regular attach */
2056 f_TC_attach(id);
2057
2058 /* Use this CTX ACT to send initial Restart counter to SGSN. */
2059 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
2060 apars.exp_rej_cause := '1a'O; /* insufficient resources */
2061 f_pdp_ctx_act(apars, true);
2062
2063 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
2064/* received. */
2065 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
2066
2067 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
2068 would be great to have an active pdp context here before triggering
2069 Recovery, and making sure the the DEACT request is sent by the SGSN.
2070 */
2071
2072 /* Activate a pdp context against the GGSN, send incremented Recovery
2073 IE. This should trigger the recovery path, but still this specific
2074 CTX activation should work. */
2075 apars.exp_rej_cause := omit; /* default value for tests */
2076 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
2077 f_pdp_ctx_act(apars, true);
2078
2079 setverdict(pass);
2080}
2081/* ATTACH + trigger Recovery procedure through CreatePdpResp */
2082testcase TC_attach_restart_ctr_create() runs on test_CT {
2083 var BSSGP_ConnHdlr vc_conn;
2084 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002085 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 +02002086 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002087 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002088}
2089
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002090/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
2091private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
2092 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2093 var integer seq_nr := 23;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01002094 var Gtp1cPeer peer;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002095 var integer i;
2096
2097 /* first perform regular attach */
2098 f_TC_attach(id);
2099 /* then activate PDP context */
2100 f_pdp_ctx_act(apars);
2101
Alexander Couzens0e510e62018-07-28 23:06:00 +02002102 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002103 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2104 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
2105
2106 for (i := 0; i < 5; i := i+1) {
2107 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002108 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002109 [] as_xid(apars);
2110 }
2111 }
2112
2113 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
2114
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002115 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002116 setverdict(pass);
2117}
2118testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
2119 var BSSGP_ConnHdlr vc_conn;
2120 f_init();
2121 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002122 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 +02002123 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002124 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002125}
2126
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002127/* ATTACH + PDP CTX ACT dropped + retrans */
2128private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2129 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2130 var Gtp1cUnitdata g_ud_first, g_ud_second;
2131 /* first perform regular attach */
2132 f_TC_attach(id);
2133
2134 /* then activate PDP context on the Gb side */
2135 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2136 apars.apn, apars.pco), 0);
2137
2138 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2139 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2140 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2141 if (g_ud_first != g_ud_second) {
2142 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2143 mtc.stop;
2144 }
2145 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2146 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2147 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2148 apars.sgsn_tei_c, apars.gtp_resp_cause,
2149 apars.ggsn_tei_c, apars.ggsn_tei_u,
2150 apars.nsapi,
2151 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2152 omit, omit));
2153 }
Harald Welte955aa942019-05-03 01:29:29 +02002154 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002155
2156 /* Now the same with Deact */
2157 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2158 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2159 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2160 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2161 if (g_ud_first != g_ud_second) {
2162 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2163 mtc.stop;
2164 }
2165 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2166 BSSGP[0].clear;
2167 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2168 }
2169 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002170 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002171 setverdict(pass);
2172 }
2173 [] as_xid(apars, 0);
2174 }
2175
2176 setverdict(pass);
2177}
2178testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2179 var BSSGP_ConnHdlr vc_conn;
2180 f_init();
2181 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2182 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002183 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002184}
2185
2186/* Test that SGSN GTP response retransmit queue works fine */
2187private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2188 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2189 var integer seq_nr := 23;
2190 var Gtp1cUnitdata g_ud_first, g_ud_second;
2191 var template Gtp1cUnitdata g_delete_req;
2192 /* first perform regular attach + PDP context act */
2193 f_TC_attach(id);
2194 f_pdp_ctx_act(apars);
2195
2196 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2197 BSSGP[0].clear;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01002198 var Gtp1cPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002199 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2200 GTP.send(g_delete_req);
2201 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002202 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002203 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2204 }
2205 [] as_xid(apars, 0);
2206 }
2207 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2208 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2209 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2210 mtc.stop;
2211 }
2212 };
2213
2214 /* Send duplicate DeleteCtxReq */
2215 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2216 GTP.send(g_delete_req);
2217 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2218 if (g_ud_first != g_ud_second) {
2219 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2220 mtc.stop;
2221 }
2222 }
2223
2224 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2225 * is handled differently by SGSN (expect "non-existent" cause) */
2226 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2227 GTP.send(g_delete_req);
2228 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2229 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2230 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2231 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2232 mtc.stop;
2233 }
2234 }
2235
2236 setverdict(pass);
2237}
2238testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2239 var BSSGP_ConnHdlr vc_conn;
2240 f_init();
2241 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2242 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002243 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002244}
2245
Alexander Couzens5e307b42018-05-22 18:12:20 +02002246private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2247 /* MS: perform regular attach */
2248 f_TC_attach(id);
2249
2250 /* HLR: cancel the location request */
2251 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2252 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002253
2254 /* ensure no Detach Request got received */
2255 timer T := 5.0;
2256 T.start;
2257 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002258 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002259 T.stop;
2260 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002261 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002262 }
2263 [] T.timeout {
2264 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002265 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002266 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002267 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002268 repeat;
2269 }
2270 }
2271}
2272
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002273/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2274private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2275 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2276
2277 /* first perform regular attach */
2278 f_TC_attach(id);
2279 /* then activate PDP context */
2280 f_pdp_ctx_act(apars);
2281 /* then transceive a downlink PDU */
2282 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2283
2284 /* Send Error indication as response from upload PDU and expect deact towards MS */
2285 f_pdp_ctx_deact_mt(apars, true);
2286}
2287testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2288 var BSSGP_ConnHdlr vc_conn;
2289 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002290 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 +02002291 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002292 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002293}
2294
Alexander Couzens5e307b42018-05-22 18:12:20 +02002295testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2296 /* MS <-> SGSN: GMM Attach
2297 * HLR -> SGSN: Cancel Location Request
2298 * HLR <- SGSN: Cancel Location Ack
2299 */
2300 var BSSGP_ConnHdlr vc_conn;
2301 f_init();
2302 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002303 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002304 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002305 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002306}
2307
2308
Alexander Couzensc87967a2018-05-22 16:09:54 +02002309private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2310 /* MS: perform regular attach */
2311 f_TC_attach(id);
2312
2313 /* HLR: cancel the location request */
2314 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2315 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2316 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2317
2318 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002319 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002320 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002321
2322 setverdict(pass);
2323}
2324
2325testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2326 /* MS <-> SGSN: GMM Attach
2327 * HLR -> SGSN: Cancel Location Request
2328 * HLR <- SGSN: Cancel Location Ack
2329 * MS <- SGSN: Detach Request
2330 * SGSN-> MS: Detach Complete
2331 */
2332 var BSSGP_ConnHdlr vc_conn;
2333 f_init();
2334 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002335 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002336 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002337 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002338}
2339
2340
Alexander Couzens6c47f292018-05-22 17:09:49 +02002341private function f_hlr_location_cancel_request_unknown_subscriber(
2342 charstring id,
2343 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2344
2345 /* HLR: cancel the location request */
2346 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2347
2348 /* cause 2 = IMSI_UNKNOWN */
2349 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2350
2351 setverdict(pass);
2352}
2353
2354private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002355 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002356}
2357
2358testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2359 /* HLR -> SGSN: Cancel Location Request
2360 * HLR <- SGSN: Cancel Location Error
2361 */
2362
2363 var BSSGP_ConnHdlr vc_conn;
2364 f_init();
2365 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002366 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 +02002367 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002368 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002369}
2370
2371private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002372 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002373}
2374
2375testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2376 /* HLR -> SGSN: Cancel Location Request
2377 * HLR <- SGSN: Cancel Location Error
2378 */
2379
2380 var BSSGP_ConnHdlr vc_conn;
2381 f_init();
2382 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002383 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 +02002384 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002385 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002386}
2387
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002388private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2389 f_TC_attach(id);
2390 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2391}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002392
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002393testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2394 /* MS <-> SGSN: Attach
2395 * MS -> SGSN: Detach Req (Power off)
2396 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2397 */
2398 var BSSGP_ConnHdlr vc_conn;
2399 var integer id := 33;
2400 var charstring imsi := hex2str(f_gen_imsi(id));
2401
2402 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002403 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002404 vc_conn.done;
2405
2406 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002407 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002408}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002409
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002410/* Attempt an attach, but loose the Identification Request (IMEI) */
2411private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2412 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002413 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002414
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002415 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 +02002416
2417 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002418 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002419 /* break */
2420 }
Harald Welte955aa942019-05-03 01:29:29 +02002421 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002422 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002423 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002424 repeat;
2425 }
Harald Welte955aa942019-05-03 01:29:29 +02002426 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002427 /* ignore ID REQ IMEI */
2428 count_req := count_req + 1;
2429 repeat;
2430 }
2431 }
2432 if (count_req != 5) {
2433 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002434 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002435 }
2436 setverdict(pass);
2437}
2438
2439testcase TC_attach_no_imei_response() runs on test_CT {
2440 /* MS -> SGSN: Attach Request IMSI
2441 * MS <- SGSN: Identity Request IMSI (optional)
2442 * MS -> SGSN: Identity Response IMSI (optional)
2443 * MS <- SGSN: Identity Request IMEI
2444 * MS -x SGSN: no response
2445 * MS <- SGSN: re-send: Identity Request IMEI 4x
2446 * MS <- SGSN: Attach Reject
2447 */
2448 var BSSGP_ConnHdlr vc_conn;
2449 f_init();
2450 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002451 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 +02002452 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002453 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002454}
2455
Alexander Couzens53f20562018-06-12 16:24:12 +02002456/* Attempt an attach, but loose the Identification Request (IMSI) */
2457private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2458 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002459 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002460
2461 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2462 g_pars.p_tmsi := 'c0000035'O;
2463
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002464 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 +02002465
2466 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002467 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002468 /* break */
2469 }
Harald Welte955aa942019-05-03 01:29:29 +02002470 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002471 /* ignore ID REQ IMSI */
2472 count_req := count_req + 1;
2473 repeat;
2474 }
Harald Welte955aa942019-05-03 01:29:29 +02002475 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002476 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002477 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002478 repeat;
2479 }
2480 }
2481 if (count_req != 5) {
2482 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002483 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002484 }
2485 setverdict(pass);
2486}
2487
2488testcase TC_attach_no_imsi_response() runs on test_CT {
2489 /* MS -> SGSN: Attach Request TMSI (unknown)
2490 * MS <- SGSN: Identity Request IMEI (optional)
2491 * MS -> SGSN: Identity Response IMEI (optional)
2492 * MS <- SGSN: Identity Request IMSI
2493 * MS -x SGSN: no response
2494 * MS <- SGSN: re-send: Identity Request IMSI 4x
2495 * MS <- SGSN: Attach Reject
2496 */
2497 var BSSGP_ConnHdlr vc_conn;
2498 f_init();
2499 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002500 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 +02002501 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002502 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002503}
2504
Alexander Couzenscf818962018-06-05 18:00:00 +02002505private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2506 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2507}
2508
2509testcase TC_attach_check_subscriber_list() runs on test_CT {
2510 /* MS <-> SGSN: Attach
2511 * VTY -> SGSN: Check if MS is in subscriber cache
2512 */
2513 var BSSGP_ConnHdlr vc_conn;
2514 var integer id := 34;
2515 var charstring imsi := hex2str(f_gen_imsi(id));
2516
2517 f_init();
2518 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002519 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002520 vc_conn.done;
2521
2522 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2523 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002524 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002525}
2526
Alexander Couzensf9858652018-06-07 16:14:53 +02002527private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2528 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002529 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002530
2531 /* unregister the old IMSI */
2532 f_bssgp_client_unregister(g_pars.imsi);
2533 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002534 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002535 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002536
2537 /* there is no auth */
2538 g_pars.net.expect_auth := false;
2539
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002540 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002541 f_gmm_auth();
2542 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002543 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002544 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002545 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002546 }
Harald Welte955aa942019-05-03 01:29:29 +02002547 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2548 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002549 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002550 setverdict(pass);
2551 }
2552 }
2553}
Alexander Couzens03d12242018-08-07 16:13:52 +02002554
2555private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2556
2557 f_TC_attach_closed_foreign(id);
2558 f_TC_attach_closed_imsi_added(id);
2559
2560}
2561
2562
Alexander Couzensf9858652018-06-07 16:14:53 +02002563testcase TC_attach_closed_add_vty() runs on test_CT {
2564 /* VTY-> SGSN: policy close
2565 * MS -> SGSN: Attach Request
2566 * MS <- SGSN: Identity Request IMSI
2567 * MS -> SGSN: Identity Response IMSI
2568 * MS <- SGSN: Attach Reject
2569 * VTY-> SGSN: policy imsi-acl add IMSI
2570 * MS -> SGSN: Attach Request
2571 * MS <- SGSN: Identity Request IMSI
2572 * MS -> SGSN: Identity Response IMSI
2573 * MS <- SGSN: Identity Request IMEI
2574 * MS -> SGSN: Identity Response IMEI
2575 * MS <- SGSN: Attach Accept
2576 */
2577 var BSSGP_ConnHdlr vc_conn;
2578 f_init();
2579 f_sleep(1.0);
2580 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2581 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002582 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2583 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002584 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002585 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002586 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002587 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002588}
2589
Alexander Couzens0085bd72018-06-12 19:08:44 +02002590/* Attempt an attach, but never answer a Attach Complete */
2591private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2592 var integer count_req := 0;
2593
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002594 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 +02002595 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002596 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07002597 as_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002598
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002599 timer T := 10.0;
2600 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002601 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002602 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002603 /* break */
2604 }
Harald Welte955aa942019-05-03 01:29:29 +02002605 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002606 /* ignore */
2607 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002608 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002609 repeat;
2610 }
2611 }
2612 if (count_req != 5) {
2613 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002614 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002615 }
2616 setverdict(pass);
2617}
2618
2619testcase TC_attach_check_complete_resend() runs on test_CT {
2620 /* MS -> SGSN: Attach Request IMSI
2621 * MS <- SGSN: Identity Request *
2622 * MS -> SGSN: Identity Response *
2623 * MS <- SGSN: Attach Complete 5x
2624 */
2625 var BSSGP_ConnHdlr vc_conn;
2626 f_init();
2627 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002628 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 +02002629 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002630 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002631}
2632
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002633friend altstep as_routing_area_update_gb(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002634 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002635
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002636 [] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002637 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2638 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002639 setverdict(pass);
2640 }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002641 [] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
2642 setverdict(fail, "Unexpected RAU Reject");
2643 mtc.stop;
2644 }
2645}
2646friend altstep as_routing_area_update_iu(integer ran_index := 0) runs on BSSGP_ConnHdlr {
2647 var PDU_DTAP_PS_MT mt;
2648
2649 [] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002650 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2651 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002652 setverdict(pass);
2653 }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002654 [] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002655 setverdict(fail, "Unexpected RAU Reject");
2656 mtc.stop;
2657 }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002658 [] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?,
2659 uia_key := oct2bit(g_pars.vec.ik),
2660 key_sts := ?)) {
2661 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2662 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
2663 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
2664 repeat;
2665 }
2666}
2667friend altstep as_routing_area_update(integer ran_index := 0) runs on BSSGP_ConnHdlr {
2668 [is_gb(ran_index)] as_routing_area_update_gb(ran_index);
2669 [is_iu(ran_index)] as_routing_area_update_iu(ran_index);
2670}
Alexander Couzens5d56f522019-09-03 12:36:18 +02002671
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002672friend function f_routing_area_update(RoutingAreaIdentificationV old_ra,
2673 GprsUpdateType upd_type := GPRS_UPD_T_RA,
2674 integer ran_index := 0,
2675 float Tval := 2.0) runs on BSSGP_ConnHdlr {
2676 var template (omit) OCT4 p_tmsi := omit;
2677 timer T := Tval;
2678
2679 if (is_iu(ran_index)) {
2680 p_tmsi := g_pars.p_tmsi;
2681 }
2682
2683 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), upd_type, old_ra, p_tmsi := p_tmsi), ran_index);
2684
2685 T.start;
2686 alt {
2687 [] as_routing_area_update(ran_index) { setverdict(pass); }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002688 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2689 [is_iu(ran_index)] BSSAP.receive { repeat; }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002690 [] T.timeout {
2691 setverdict(fail, "Timeout completing the RAU procedure");
2692 mtc.stop;
2693 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002694 }
2695}
2696
Alexander Couzensbfda9212018-07-31 03:17:33 +02002697private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002698 /* first perform regular attach */
2699 f_TC_attach(id);
2700
2701 /* then send RAU */
2702 f_routing_area_update(g_pars.ra);
2703
2704 /* do another RAU */
2705 f_routing_area_update(g_pars.ra);
2706
2707 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2708}
2709
2710testcase TC_attach_rau_a_a() runs on test_CT {
2711 /* MS <-> SGSN: Successful Attach
2712 * MS -> SGSN: Routing Area Update Request
2713 * MS <- SGSN: Routing Area Update Accept
2714 * MS -> SGSN: Routing Area Update Request
2715 * MS <- SGSN: Routing Area Update Accept
2716 * MS -> SGSN: Detach (PowerOff)
2717 */
2718 var BSSGP_ConnHdlr vc_conn;
2719 f_init();
2720 f_sleep(1.0);
2721 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2722 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002723 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002724}
2725
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002726private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002727 f_TC_attach(id);
2728
2729 log("attach complete sending rau");
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002730 f_routing_area_update(g_pars.ra);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002731
2732 log("rau complete unregistering");
2733 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002734 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002735
2736 log("sending second RAU via different RA");
Vadim Yanitskiyaaf7ce42024-04-21 20:46:51 +07002737 f_routing_area_update(old_ra := g_pars.ra, ran_index := 1);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002738
2739 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2740}
2741
2742testcase TC_attach_rau_a_b() runs on test_CT {
2743 /* MS <-> SGSN: Successful Attach
2744 * MS -> SGSN: Routing Area _a_ Update Request
2745 * MS <- SGSN: Routing Area _a_ Update Accept
2746 * MS -> SGSN: Routing Area _b_ Update Request
2747 * MS <- SGSN: Routing Area _b_ Update Accept
2748 * MS -> SGSN: Detach (PowerOff)
2749 */
2750 var BSSGP_ConnHdlr vc_conn;
2751 f_init();
2752 f_sleep(1.0);
2753 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2754 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002755 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002756}
2757
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002758private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2759 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002760 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002761 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002762 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002763
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002764 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002765
2766 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002767 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002768 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2769 mtc.stop;
2770 }
Harald Welte955aa942019-05-03 01:29:29 +02002771 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002772 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002773 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002774 repeat;
2775 }
Harald Welte955aa942019-05-03 01:29:29 +02002776 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002777 /* send out a second GMM_Attach Request.
2778 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2779 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002780 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002781 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002782 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002783 }
2784 }
2785 f_sleep(1.0);
2786
2787 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2788 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002789 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002790 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002791 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002792 repeat;
2793 }
Harald Welte955aa942019-05-03 01:29:29 +02002794 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002795 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2796 mtc.stop;
2797 }
Harald Welte955aa942019-05-03 01:29:29 +02002798 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002799 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2800 mtc.stop;
2801 }
Harald Welte955aa942019-05-03 01:29:29 +02002802 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2803 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002804 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002805 setverdict(pass);
2806 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2807 }
2808 }
2809}
2810
2811testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2812 /* Testing if the SGSN ignore Attach Request with the exact same content */
2813 /* MS -> SGSN: Attach Request IMSI
2814 * MS <- SGSN: Identity Request IMSI (optional)
2815 * MS -> SGSN: Identity Response IMSI (optional)
2816 * MS <- SGSN: Identity Request IMEI
2817 * MS -> SGSN: Attach Request (2nd)
2818 * MS <- SGSN: Identity Response IMEI
2819 * MS <- SGSN: Attach Accept
2820 * MS -> SGSN: Attach Complete
2821 */
2822 var BSSGP_ConnHdlr vc_conn;
2823 f_init();
2824 f_sleep(1.0);
2825 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2826 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2827 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002828 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002829}
2830
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002831private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002832 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2833
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002834 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 +02002835
2836 /* send Attach Request */
2837 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2838 * 3G auth vectors */
2839 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2840 /* The thing is, if the solSACapability is 'omit', then the
2841 * revisionLevelIndicatior is at the wrong place! */
2842 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002843 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002844
2845 /* do the auth */
2846 var PDU_L3_MS_SGSN l3_mo;
2847 var PDU_L3_SGSN_MS l3_mt;
2848 var default di := activate(as_mm_identity());
2849
2850 var GSUP_IE auth_tuple;
2851 var template AuthenticationParameterAUTNTLV autn;
2852
2853 g_pars.vec := f_gen_auth_vec_3g();
2854 autn := {
2855 elementIdentifier := '28'O,
2856 lengthIndicator := lengthof(g_pars.vec.autn),
2857 autnValue := g_pars.vec.autn
2858 };
2859 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2860 g_pars.vec.sres,
2861 g_pars.vec.kc,
2862 g_pars.vec.ik,
2863 g_pars.vec.ck,
2864 g_pars.vec.autn,
2865 g_pars.vec.res));
2866 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2867 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2868 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2869
2870 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2871 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002872 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002873
2874 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002875 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002876
2877 /* wait for the GSUP resync request */
2878 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2879 g_pars.imsi,
2880 g_pars.vec.auts,
2881 g_pars.vec.rand));
2882
2883 /* generate new key material */
2884 g_pars.vec := f_gen_auth_vec_3g();
2885 autn := {
2886 elementIdentifier := '28'O,
2887 lengthIndicator := lengthof(g_pars.vec.autn),
2888 autnValue := g_pars.vec.autn
2889 };
2890
2891 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2892 g_pars.vec.sres,
2893 g_pars.vec.kc,
2894 g_pars.vec.ik,
2895 g_pars.vec.ck,
2896 g_pars.vec.autn,
2897 g_pars.vec.res));
2898 /* send new key material */
2899 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2900
2901 /* wait for the new Auth Request */
2902 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2903 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002904 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002905 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002906 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 +02002907 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2908 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2909 valueField := substr(g_pars.vec.res, 0, 4)
2910 };
2911 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2912 elementIdentifier := '21'O,
2913 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2914 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2915 };
2916 l3_mo := valueof(auth_ciph_resp);
2917 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2918 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2919 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2920 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2921 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002922 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002923 deactivate(di);
2924
2925 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07002926 as_gmm_gsup_lu_isd();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002927
Harald Welte955aa942019-05-03 01:29:29 +02002928 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2929 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002930 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002931 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002932 setverdict(pass);
2933}
2934
2935testcase TC_attach_usim_resync() runs on test_CT {
2936 /* MS -> SGSN: Attach Request
2937 * MS <- SGSN: Identity Request IMSI
2938 * MS -> SGSN: Identity Response IMSI
2939 * MS <- SGSN: Identity Request IMEI
2940 * MS -> SGSN: Identity Response IMEI
2941 * HLR<- SGSN: SAI Request
2942 * HLR-> SGSN: SAI Response
2943 * MS <- SGSN: Auth Request
2944 * MS -> SGSN: Auth Failure (with AUTS)
2945 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2946 * HLR-> SGSN: SAI Response (new key material)
2947 * MS <- SGSN: Auth Request (new key material)
2948 * MS -> SGSN: Auth Response
2949 * MS <- SGSN: Attach Accept
2950 * MS -> SGSN: Attach Complete
2951 */
2952 var BSSGP_ConnHdlr vc_conn;
2953 f_init();
2954 f_sleep(1.0);
2955 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2956 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002957 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002958}
2959
Eric Wildc555be52021-05-15 19:48:22 +02002960private function f_TC_attach_usim_crypt(OCT1 netcap_a2345, BIT3 auth_req_ciph) runs on BSSGP_ConnHdlr {
2961 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2962
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002963 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 +02002964 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.spare_octets := netcap_a2345; /* GEA2345... */
2965
2966 /* send Attach Request */
2967 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2968 * 3G auth vectors */
2969 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2970 /* The thing is, if the solSACapability is 'omit', then the
2971 * revisionLevelIndicatior is at the wrong place! */
2972 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2973 f_send_l3(attach_req);
2974
2975 /* do the auth */
2976 var PDU_L3_MS_SGSN l3_mo;
2977 var PDU_L3_SGSN_MS l3_mt;
2978 var default di := activate(as_mm_identity());
2979
2980 var GSUP_IE auth_tuple;
2981 var template AuthenticationParameterAUTNTLV autn;
2982
2983 g_pars.vec := f_gen_auth_vec_3g();
2984 autn := {
2985 elementIdentifier := '28'O,
2986 lengthIndicator := lengthof(g_pars.vec.autn),
2987 autnValue := g_pars.vec.autn
2988 };
2989 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2990 g_pars.vec.sres,
2991 g_pars.vec.kc,
2992 g_pars.vec.ik,
2993 g_pars.vec.ck,
2994 g_pars.vec.autn,
2995 g_pars.vec.res));
2996 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2997 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2998 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2999
3000 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand, auth_req_ciph);
3001 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
3002 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
3003
3004 setverdict(pass);
3005 deactivate(di);
3006}
3007
3008private function f_TC_attach_usim_a54_a54(charstring id) runs on BSSGP_ConnHdlr {
3009 f_TC_attach_usim_crypt('10'O, '100'B);
3010}
3011
3012private function f_TC_attach_usim_a54_a53(charstring id) runs on BSSGP_ConnHdlr {
3013 f_TC_attach_usim_crypt('20'O, '011'B);
3014}
3015
3016private function f_TC_attach_usim_a53_a54(charstring id) runs on BSSGP_ConnHdlr {
3017 f_TC_attach_usim_crypt('30'O, '011'B);
3018}
3019
3020private function f_TC_attach_usim_a50_a54(charstring id) runs on BSSGP_ConnHdlr {
3021 f_TC_attach_usim_crypt('30'O, '000'B);
3022}
3023
3024private function f_TC_attach_usim_a54_a50(charstring id) runs on BSSGP_ConnHdlr {
3025 f_TC_attach_usim_crypt('00'O, '000'B);
3026}
3027
3028testcase TC_attach_usim_a54_a54() runs on test_CT {
3029 var BSSGP_ConnHdlr vc_conn;
3030 f_init();
3031 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003032 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003033 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a54), testcasename(), g_gb, 40);
3034 vc_conn.done;
3035 f_cleanup();
3036}
3037
3038testcase TC_attach_usim_a54_a53() runs on test_CT {
3039 var BSSGP_ConnHdlr vc_conn;
3040 f_init();
3041 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003042 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003043 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a53), testcasename(), g_gb, 40);
3044 vc_conn.done;
3045 f_cleanup();
3046}
3047
3048testcase TC_attach_usim_a53_a54() runs on test_CT {
3049 var BSSGP_ConnHdlr vc_conn;
3050 f_init();
3051 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003052 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3");
Eric Wildc555be52021-05-15 19:48:22 +02003053 vc_conn := f_start_handler(refers(f_TC_attach_usim_a53_a54), testcasename(), g_gb, 40);
3054 vc_conn.done;
3055 f_cleanup();
3056}
3057
3058testcase TC_attach_usim_a50_a54() runs on test_CT {
3059 var BSSGP_ConnHdlr vc_conn;
3060 f_init();
3061 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003062 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0");
Eric Wildc555be52021-05-15 19:48:22 +02003063 vc_conn := f_start_handler(refers(f_TC_attach_usim_a50_a54), testcasename(), g_gb, 40);
3064 vc_conn.done;
3065 f_cleanup();
3066}
3067
3068testcase TC_attach_usim_a54_a50() runs on test_CT {
3069 var BSSGP_ConnHdlr vc_conn;
3070 f_init();
3071 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003072 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003073 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a50), testcasename(), g_gb, 40);
3074 vc_conn.done;
3075 f_cleanup();
3076}
Harald Weltea05b8072019-04-23 22:35:05 +02003077
3078/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
3079private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
3080 f_gmm_attach(false, false);
3081 f_sleep(1.0);
3082 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
3083 /* try to detach to check if SGSN is still alive */
3084 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
3085}
3086testcase TC_llc_null() runs on test_CT {
3087 var BSSGP_ConnHdlr vc_conn;
3088 f_init();
3089 f_sleep(1.0);
3090 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
3091 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003092 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02003093}
3094
Harald Welte645a1512019-04-23 23:18:23 +02003095/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3096private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
3097 f_gmm_attach(false, false);
3098 f_sleep(1.0);
3099 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003100 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003101 setverdict(pass);
3102}
3103testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
3104 var BSSGP_ConnHdlr vc_conn;
3105 f_init();
3106 f_sleep(1.0);
3107 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
3108 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003109 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003110}
3111
3112/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3113private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
3114 f_gmm_attach(false, false);
3115 f_sleep(1.0);
3116 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003117 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003118 setverdict(pass);
3119}
3120testcase TC_llc_sabm_dm_ll5() runs on test_CT {
3121 var BSSGP_ConnHdlr vc_conn;
3122 f_init();
3123 f_sleep(1.0);
3124 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
3125 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003126 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003127}
3128
Harald Welte2aaac1b2019-05-02 10:02:53 +02003129/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
3130private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
3131 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3132 var template (value) XID_Information xid;
3133 var template XID_Information xid_rx;
3134
3135 /* first perform regular attach */
3136 f_TC_attach(id);
3137 /* then activate PDP context */
3138 f_pdp_ctx_act(apars);
3139
3140 /* start MO XID */
3141 xid := { ts_XID_L3(''O) };
3142 xid_rx := { tr_XID_L3(''O) };
3143 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3144 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003145 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003146 [] as_xid(apars);
3147 }
3148 setverdict(pass);
3149}
3150testcase TC_xid_empty_l3() runs on test_CT {
3151 var BSSGP_ConnHdlr vc_conn;
3152 f_init();
3153 f_sleep(1.0);
3154 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
3155 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003156 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003157}
3158
3159private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
3160 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3161 var template (value) XID_Information xid;
3162 var template XID_Information xid_rx;
3163
3164 /* first perform regular attach */
3165 f_TC_attach(id);
3166 /* then activate PDP context */
3167 f_pdp_ctx_act(apars);
3168
3169 /* start MO XID */
3170 xid := { ts_XID_N201U(1234) };
3171 xid_rx := { tr_XID_N201U(1234) };
3172 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3173 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003174 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003175 [] as_xid(apars);
3176 }
3177 setverdict(pass);
3178}
3179testcase TC_xid_n201u() runs on test_CT {
3180 var BSSGP_ConnHdlr vc_conn;
3181 f_init();
3182 f_sleep(1.0);
3183 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
3184 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003185 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003186}
3187
Alexander Couzens6bee0872019-05-11 01:48:50 +02003188private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
3189 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3190
3191 /* first perform regular attach */
3192 f_TC_attach(id);
3193 /* then activate PDP context */
3194 f_pdp_ctx_act(apars);
3195 /* do a normal detach */
3196 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
3197}
3198
3199testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
3200 /* MS -> SGSN: Attach Request
3201 * MS <-> SGSN: [..]
3202 * MS -> SGSN: Attach Complete
3203 * MS -> SGSN: PDP Activate Request
3204 * MS <- SGSN: PDP Activate Accept
3205 * MS -> SGSN: GMM Detach Request
3206 * MS <- SGSN: GMM Detach Accept
3207 */
3208 var BSSGP_ConnHdlr vc_conn;
3209 f_init();
3210 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
3211 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003212 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02003213}
Harald Welte645a1512019-04-23 23:18:23 +02003214
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003215private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
3216 var RoutingAreaIdentificationV old_ra := f_random_RAI();
3217 var RoutingAreaIdentificationV new_ra := f_random_RAI();
3218 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003219 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 +01003220 var PDU_L3_SGSN_MS l3_mt;
3221
3222 f_send_l3(attach_req, 0);
3223
3224 BSSGP[0].receive(tr_GMM_ID_REQ(?));
3225
3226 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
3227 alt {
3228 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
3229 setverdict(pass);
3230 }
3231 [] BSSGP[0].receive { repeat; }
3232 }
3233}
3234
3235/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
3236 * See OS#3957 and OS#4245 for more information.
3237 */
3238testcase TC_attach_req_id_req_ra_update() runs on test_CT {
3239 /*
3240 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
3241 * MS <-- SGSN: Identity Request (IMEI)
3242 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
3243 */
3244 var BSSGP_ConnHdlr vc_conn;
3245 f_init();
3246 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
3247 vc_conn.done;
3248 f_cleanup();
3249}
3250
Harald Welte8e5932e2020-06-17 22:12:54 +02003251private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
3252var PDU_BSSGP rx;
3253[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
3254 setverdict(fail, "Received unexpected PS PAGING: ", rx);
3255 mtc.stop;
3256 }
3257}
3258
3259/* SUSPEND, then DL traffic: should not pass + no paging expected */
3260private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3261 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3262 var default d;
3263
3264 /* first perform regular attach */
3265 f_TC_attach(id);
3266 /* then activate PDP context */
3267 f_pdp_ctx_act(apars);
3268 /* then transceive a downlink PDU */
3269 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3270
3271 /* now suspend GPRS */
3272 f_bssgp_suspend();
3273
3274 d := activate(as_nopaging_ps());
3275
3276 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3277 * nor any related paging requests */
3278 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3279
3280 deactivate(d);
3281}
3282testcase TC_suspend_nopaging() runs on test_CT {
3283 var BSSGP_ConnHdlr vc_conn;
3284 f_init();
3285 f_sleep(1.0);
3286 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3287 vc_conn.done;
3288 f_cleanup();
3289}
3290
3291
3292/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3293private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3294 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3295 var OCT1 susp_ref;
3296 var default d;
3297
3298 /* first perform regular attach */
3299 f_TC_attach(id);
3300 /* then activate PDP context */
3301 f_pdp_ctx_act(apars);
3302 /* then transceive a downlink PDU */
3303 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3304
3305 /* now suspend GPRS */
3306 susp_ref := f_bssgp_suspend();
3307
3308 d := activate(as_nopaging_ps());
3309
3310 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3311 * nor any related paging requests */
3312 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3313
3314 deactivate(d);
3315
3316 /* resume GPRS */
3317 f_bssgp_resume(susp_ref);
3318
3319 /* now data should be flowing again */
3320 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3321}
3322testcase TC_suspend_resume() runs on test_CT {
3323 var BSSGP_ConnHdlr vc_conn;
3324 f_init();
3325 f_sleep(1.0);
3326 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3327 vc_conn.done;
3328 f_cleanup();
3329}
3330
3331/* SUSPEND, then RAU: data expected to flow after implicit resume */
3332private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3333 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3334 var default d;
3335
3336 /* first perform regular attach */
3337 f_TC_attach(id);
3338 /* then activate PDP context */
3339 f_pdp_ctx_act(apars);
3340 /* then transceive a downlink PDU */
3341 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3342
3343 /* now suspend GPRS */
3344 f_bssgp_suspend();
3345
3346 d := activate(as_nopaging_ps());
3347
3348 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3349 * nor any related paging requests */
3350 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3351
3352 deactivate(d);
3353
3354 /* perform RAU (implicit RESUME) */
3355 f_routing_area_update(g_pars.ra);
3356
Harald Welted5836dc2021-03-20 15:40:00 +01003357 /* give SGSN some time to actually receve + process the RAU Complete we sent */
3358 f_sleep(0.5);
3359
Harald Welte8e5932e2020-06-17 22:12:54 +02003360 /* now data should be flowing again */
3361 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3362
3363}
3364testcase TC_suspend_rau() runs on test_CT {
3365 var BSSGP_ConnHdlr vc_conn;
3366 f_init();
3367 f_sleep(1.0);
3368 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3369 vc_conn.done;
3370 f_cleanup();
3371}
3372
3373
3374/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3375private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3376 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3377 var default d;
3378
3379 /* first perform regular attach */
3380 f_TC_attach(id);
3381 /* then activate PDP context */
3382 f_pdp_ctx_act(apars);
3383 /* then transceive a downlink PDU */
3384 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3385
3386 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3387 f_sleep(5.0);
3388
3389 /* now data should be flowing again, but with PS PAGING */
3390 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3391 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3392
3393 /* FIXME: simulate paging response */
3394 /* FIXME: verify PDU actually arrives only after paging response was successful */
3395
3396}
3397testcase TC_paging_ps() runs on test_CT {
3398 var BSSGP_ConnHdlr vc_conn;
3399 f_init();
3400 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3401 f_sleep(1.0);
3402 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3403 vc_conn.done;
3404 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3405 f_cleanup();
3406}
3407
Philipp Maier7df55e02020-12-14 23:46:04 +01003408/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3409 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3410 * other and vice versa. */
3411testcase TC_bssgp_rim_single_report() runs on test_CT {
3412 var BSSGP_ConnHdlr vc_conn;
3413 f_init();
Philipp Maier7df55e02020-12-14 23:46:04 +01003414
3415 timer T := 2.0;
3416
3417 var template RIM_Routing_Address dst_addr;
3418 var template RIM_Routing_Address src_addr;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003419 var template (value) RAN_Information_Request_RIM_Container req_cont;
3420 var template (value) RAN_Information_RIM_Container res_cont;
3421 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maier7df55e02020-12-14 23:46:04 +01003422 var template PDU_BSSGP bssgp_rim_pdu_expect;
3423
3424 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3425 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003426
3427
Philipp Maier7df55e02020-12-14 23:46:04 +01003428 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3429 * based on the cell id in dst_addr to GB interface #1. */
3430 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3431 ts_RIM_Sequence_Number(1),
3432 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3433 ts_RIM_Protocol_Version_Number(1),
3434 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3435 omit);
3436 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3437 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3438 req_cont);
3439 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3440 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3441 tr_RAN_Information_Request_RIM_Container);
3442 RIM[0].send(bssgp_rim_pdu);
3443 T.start;
3444 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003445 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3446 setverdict(pass);
3447 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003448 [] RIM[1].receive {
3449 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003450 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003451 [] T.timeout {
3452 setverdict(fail, "No BSSGP RIM PDU received");
3453 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003454 }
3455 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003456
Philipp Maier7df55e02020-12-14 23:46:04 +01003457 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3458 * GB interface #0 */
Philipp Maier7df55e02020-12-14 23:46:04 +01003459 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3460 ts_RIM_Sequence_Number(2),
3461 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3462 ts_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003463 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 +01003464 omit);
3465 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3466 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3467 res_cont);
3468 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3469 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3470 ?);
3471 RIM[1].send(bssgp_rim_pdu);
3472 T.start;
3473 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003474 [] RIM[0].receive(bssgp_rim_pdu_expect) {
3475 setverdict(pass);
3476 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003477 [] RIM[0].receive {
3478 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003479 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003480 [] T.timeout {
3481 setverdict(fail, "No BSSGP RIM PDU received");
3482 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003483 }
3484 }
3485
3486 f_cleanup();
3487}
Harald Welte8e5932e2020-06-17 22:12:54 +02003488
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003489testcase TC_rim_eutran_to_geran() runs on test_CT {
3490 var BSSGP_ConnHdlr vc_conn;
3491 f_init();
3492 /* connect RIM related port */
3493 connect(vc_GTP:CLIENT_DEFAULT, self:GTPC);
3494
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01003495 var Gtp1cPeer peer := {
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003496 connId := 1,
3497 remName := mp_sgsn_gtp_ip,
3498 remPort := GTP1C_PORT
3499 }
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003500 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 +02003501
3502 var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
3503 var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
3504 var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
Philipp Maier7e9acc32023-08-04 17:23:12 +02003505 var template (value) RIM_RoutingAddress gtpc_rim_ra;
3506 var template (value) RIM_RoutingAddress_Discriminator gtpc_rim_ra_discr;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003507 var template (value) Gtp1cUnitdata gtpc_pdu;
3508
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003509 gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(gtp_ci);
3510 gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(gtp_ci, tac := 3, gnbid := '12345678123456'O);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003511
3512 gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3513 ts_GTPC_RIM_Sequence_Number(1),
3514 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3515 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003516 tsu_GTPC_RAN_Information_Request_Application_Container_NACC(gtp_ci),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003517 omit);
3518 gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3519 ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3520 gtpc_rim_req_cont);
Philipp Maier7e9acc32023-08-04 17:23:12 +02003521
3522 /* Assemble RIM Routing Address (essentially a copy of the destination cell identifier)*/
3523 gtpc_rim_ra := ts_RIM_RoutingAddress(enc_RIM_Routing_Address_GTPC(valueof(gtpc_dst_addr)));
3524 gtpc_rim_ra_discr := ts_RIM_RoutingAddress_Discriminator(hex2bit(RIM_ADDR_GERAN_CELL_ID));
3525 gtpc_pdu := ts_GTPC_RANInfoRelay(peer, ts_RANTransparentContainer_RAN_INFO_REQ(gtpc_bssgp_cont),
3526 gtpc_rim_ra, gtpc_rim_ra_discr);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003527 GTPC.send(gtpc_pdu);
3528
3529 var template RIM_Routing_Address bssgp_dst_addr, bssgp_src_addr;
3530 var template PDU_BSSGP bssgp_rim_pdu_expect;
3531 bssgp_dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3532 bssgp_src_addr := t_RIM_Routing_Address_enbid(g_gb[1].cfg.bvc[0].cell_id, tac := 3, gnbid := '12345678123456'O);
3533 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3534 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3535 tr_RAN_Information_Request_RIM_Container);
3536 timer T := 2.0;
3537 T.start;
3538 alt {
3539 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3540 setverdict(pass);
3541 T.stop;
3542 }
3543 [] RIM[1].receive {
3544 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3545 }
3546 [] T.timeout {
3547 setverdict(fail, "No BSSGP RIM PDU received");
3548 mtc.stop;
3549 }
3550 }
3551
3552 /* Now also emulate also the response as well and send it back on GB
3553 interface #1. Expect the result on * GTPC */
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003554 var template (value) RAN_Information_RIM_Container res_cont;
3555 var template (value) PDU_BSSGP bssgp_rim_pdu;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003556 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3557 ts_RIM_Sequence_Number(2),
3558 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3559 ts_RIM_Protocol_Version_Number(1),
3560 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[1].cfg.bvc[0].cell_id, false, 3, si_default)),
3561 omit);
3562 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3563 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3564 res_cont);
3565 RIM[1].send(bssgp_rim_pdu);
3566
3567 var template RAN_Information_RIM_Container_GTPC rim_cont;
3568 var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_cont_ack;
3569 var template Gtp1cUnitdata gtpc_pdu_exp;
3570 rim_cont := tr_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3571 ts_GTPC_RIM_Sequence_Number(2),
3572 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3573 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003574 tru_GTPC_ApplContainer_or_ApplErrContainer_NACC(tru_GTPC_ApplContainer_NACC(gtp_ci, false, 3, si_default)),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003575 omit);
3576 gtpc_bssgp_cont_ack := tr_GTPC_RAN_Information(tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3577 tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3578 rim_cont);
3579 gtpc_pdu_exp := tr_GTPC_RANInfoRelay(peer, tr_RANTransparentContainer_RAN_INFO(gtpc_bssgp_cont_ack));
3580
3581 T.start;
3582 alt {
3583 [] GTPC.receive(gtpc_pdu_exp) {
3584 setverdict(pass);
3585 T.stop;
3586 }
3587 [] GTPC.receive {
3588 setverdict(fail, "Unexpected GTPC RIM PDU received");
3589 }
3590 [] T.timeout {
3591 setverdict(fail, "No GTPC RIM PDU received");
3592 mtc.stop;
3593 }
3594 }
3595
3596 f_cleanup();
3597}
3598
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003599/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3600private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3601 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3602
3603 /* first perform regular attach */
3604 f_gmm_attach(false, false, ran_index := 0);
3605 /* then activate PDP context */
3606 f_pdp_ctx_act(apars, ran_index := 0);
3607 /* then transceive a downlink PDU */
3608 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3609 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3610
3611 /* Now attach on different cell: */
3612 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3613 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3614 g_pars.net.expect_auth := false;
3615 f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0]));
3616 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3617 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1);
3618}
3619testcase TC_cell_change_different_rai_ci_attach() runs on test_CT {
3620 var BSSGP_ConnHdlr vc_conn;
3621 f_init();
3622 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68);
3623 vc_conn.done;
3624 f_cleanup();
3625}
3626
3627/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3628/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3629private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3630 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3631
3632 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3633 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3634
3635 /* first perform regular attach */
3636 f_gmm_attach(false, false, ran_index := 1);
3637 /* then activate PDP context */
3638 f_pdp_ctx_act(apars, ran_index := 1);
3639 /* then transceive a downlink PDU */
3640 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3641 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3642
3643 /* Now attach on different cell: */
3644 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3645 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3646 g_pars.net.expect_auth := false;
3647 f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1]));
3648 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3649 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3650}
3651testcase TC_cell_change_different_ci_attach() runs on test_CT {
3652 var BSSGP_ConnHdlr vc_conn;
3653 f_init();
3654 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69);
3655 vc_conn.done;
3656 f_cleanup();
3657}
3658
3659/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */
3660private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3661 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3662
3663 /* first perform regular attach */
3664 f_gmm_attach(false, false, ran_index := 0);
3665 /* then activate PDP context */
3666 f_pdp_ctx_act(apars, ran_index := 0);
3667 /* then transceive a downlink PDU */
3668 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3669 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3670
3671 /* Send some data over new bvci, it should be silently discarded since
3672 * RAC changed and SGSN expects a RAU to occur in that case */
3673 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3674 var octetstring payload := f_rnd_octstring(200);
3675 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
3676 BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1));
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01003677 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003678 timer T := 2.0;
3679 T.start;
3680 alt {
3681 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) {
3682 setverdict(fail, "Unexpected GTP message");
3683 }
3684 [] T.timeout { setverdict(pass); }
3685 }
3686
3687 /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */
3688 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3689 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3690}
3691testcase TC_cell_change_different_rai_ci_data() runs on test_CT {
3692 var BSSGP_ConnHdlr vc_conn;
3693 f_init();
3694 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70);
3695 vc_conn.done;
3696 f_cleanup();
3697}
3698
3699/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */
3700/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3701private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3702 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3703
3704 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3705 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3706
3707 /* first perform regular attach */
3708 f_gmm_attach(false, false, ran_index := 1);
3709 /* then activate PDP context */
3710 f_pdp_ctx_act(apars, ran_index := 1);
3711 /* then transceive a downlink PDU */
3712 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3713 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3714
3715 /* Now attach on different cell: */
3716 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3717 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3718
3719 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3720 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3721}
3722testcase TC_cell_change_different_ci_data() runs on test_CT {
3723 var BSSGP_ConnHdlr vc_conn;
3724 f_init();
3725 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71);
3726 vc_conn.done;
3727 f_cleanup();
3728}
3729
Vadim Yanitskiyacd0b392024-04-06 05:38:35 +07003730/* SGSN terminated SGSN Context Request procedure (we request, SGSN responds)
3731 * 3GPP TS 23.401, Figure D.3.6-1: "Gn/Gp SGSN to MME Tracking Area Update procedure" */
3732private function f_TC_sgsn_context_req_in(charstring id) runs on BSSGP_ConnHdlr {
3733 var integer seq_nr := f_rnd_int(65535);
3734 var Gtp1cUnitdata gtpc_ud;
3735 timer T;
3736
3737 var Gtp1cPeer peer := {
3738 connId := 1,
3739 remName := mp_sgsn_gtp_ip,
3740 remPort := GTP1C_PORT
3741 }
3742
3743 /* The MS attaches to GERAN/UTRAN and enjoys the service */
3744 f_gmm_attach(false, false);
3745
3746 /* The MS switches to an LTE cell and performs Tracking Area Update Request there.
3747 * The MME requests information about the MS by sending SGSN Context Request. */
3748 var template (value) GTPC_PDUs ctx_req;
3749 ctx_req := ts_SGSNContextReqPDU(rai := ts_RoutingAreaIdentity('250'H, 'F99'H, '4242'O, 'DE'O),
3750 teic := '12345678'O,
3751 sgsn_addr_control := f_inet_addr(mp_ggsn_ip),
3752 ptmsi := ts_PTMSI(g_pars.p_tmsi),
3753 ptmsi_sig := ts_PTMSI_sig('010203'O));
3754 GTP.send(ts_GTPC_SGSNContextReq(peer, seq_nr, ctx_req));
3755
3756 /* The SGSN responds with subscriber's IMSI */
3757 var template (present) GTPC_PDUs ctx_rsp;
3758 ctx_rsp := tr_SGSNContextRespPDU(cause := GTP_CAUSE_REQUEST_ACCEPTED,
3759 imsi := g_pars.imsi);
Vadim Yanitskiy74b12c72024-04-19 01:46:07 +07003760
3761 /* SGSN Address for Control Plane */
3762 var octetstring sgsn_addr := f_inet_addr(mp_sgsn_gtp_ip);
3763 ctx_rsp.sgsn_ContextResponse.sgsn_addr_controlPlane := tr_GsnAddr(sgsn_addr);
3764
3765 /* Match MM Context */
3766 if (ispresent(g_pars.vec)) {
3767 /* XXX: this is only valid for GERAN */
3768 var octetstring triplet := g_pars.vec.rand & g_pars.vec.sres & g_pars.vec.kc;
3769 ctx_rsp.sgsn_ContextResponse.mm_Context := tr_MM_ContextGSM(kc := g_pars.vec.kc,
3770 triplet := triplet);
3771 /* TODO: 7.5.4 "The IMEISV shall, if available, be included in the MM Context".
3772 * See also 3GPP TS 29.060, section 7.7.28 and Table 47A */
3773 }
3774
3775 /* TODO: match PDP Context */
Vadim Yanitskiyacd0b392024-04-06 05:38:35 +07003776
3777 T.start(2.0);
3778 alt {
3779 [] GTP.receive(tr_GTPC_SGSNContextResp(?, ?, ctx_rsp)) -> value gtpc_ud {
3780 log("Rx SGSN Context Resp from SGSN, sending Ack");
3781 GTP.send(ts_GTPC_SGSNContextAck(gtpc_ud.peer, '12345678'O, seq_nr));
3782 setverdict(pass);
3783 }
3784 [] GTP.receive(tr_GTPC_SGSNContextResp) -> value gtpc_ud {
3785 GTP.send(ts_GTPC_SGSNContextAck(gtpc_ud.peer, '12345678'O, seq_nr,
3786 ts_SGSNContextAckPDU(GTP_CAUSE_INVALID_MSG_FORMAT)));
3787 setverdict(fail, "Rx unexpected SGSN Context Resp");
3788 }
3789 [] T.timeout {
3790 setverdict(fail, "Timeout waiting for SGSN Context Resp");
3791 }
3792 }
3793
3794 /* HLR/HSS tells SGSN to forget this MS/UE */
3795 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
3796 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
3797}
3798testcase TC_sgsn_context_req_in() runs on test_CT {
3799 var BSSGP_ConnHdlr vc_conn;
3800 f_init();
3801 f_sleep(1.0);
3802 vc_conn := f_start_handler(refers(f_TC_sgsn_context_req_in), testcasename(), g_gb, 72);
3803 vc_conn.done;
3804 f_cleanup();
3805}
3806
3807/* SGSN originated SGSN Context Request procedure (SGSN requests, we respond)
3808 * 3GPP TS 23.401, Figure D.3.5-1 "Routing Area Update procedure" */
3809private function f_TC_sgsn_context_req_out(charstring id) runs on BSSGP_ConnHdlr {
3810 var integer seq_nr := f_rnd_int(65535);
3811 var Gtp1cUnitdata gtpc_ud;
3812 timer T;
3813
3814 /* The MS goes to GERAN/UTRAN from an LTE cell */
3815 f_send_l3(ts_GMM_RAU_REQ(mi_lv := valueof(ts_MI_TMSI_LV('DE42DE42'O)),
3816 upd_type := GPRS_UPD_T_RA,
3817 old_ra := f_random_RAI()), 0);
3818
3819
3820 /* The SGSN has no idea about the MS and inquires the MME about it */
3821 T.start(2.0);
3822 alt {
3823 [] GTP.receive(tr_GTPC_SGSNContextReq(?, ?)) -> value gtpc_ud {
3824 log("Rx SGSN Context Req from SGSN");
3825 setverdict(pass);
3826 T.stop;
3827 }
3828 [] GTP.receive(tr_GTPC_SGSNContextResp) {
3829 setverdict(fail, "Rx unexpected SGSN Context Req");
3830 mtc.stop;
3831 }
3832 [] BSSGP[0].receive(tr_LLC_XID_MT_CMD(?, ?)) {
3833 /* Ignore XID Reset */
3834 repeat;
3835 }
3836 [] BSSGP[0].receive(tr_GMM_RAU_REJECT) {
3837 /* osmo-sgsn -latest would send RAU Reject (Implicitly detached) */
3838 setverdict(fail, "Rx unexpected RAU Reject");
3839 mtc.stop;
3840 }
3841 [] T.timeout {
3842 setverdict(fail, "Timeout waiting for SGSN Context Req");
3843 mtc.stop;
3844 }
3845 }
3846
3847 /* The MME responds */
3848 var OCT8 kc := f_rnd_octstring(8);
3849
3850 var template (value) PDP_Context_GTPC pdp_ctx;
3851 pdp_ctx := ts_PDP_Context_GTPC(pdp_addr := f_inet_addr("10.10.10.10"),
3852 ggsn_gsn_addr := f_inet_addr(mp_ggsn_ip),
3853 apn := '08696E7465726E6574'O);
3854
3855 var template (value) GTPC_PDUs ctx_rsp;
3856 ctx_rsp := ts_SGSNContextRespPDU(cause := GTP_CAUSE_REQUEST_ACCEPTED,
3857 imsi := g_pars.imsi,
3858 teic := '12345678'O,
3859 mm_context := ts_MM_ContextGSM(kc),
3860 pdp_ctx_list := { pdp_ctx });
3861 GTP.send(ts_GTPC_SGSNContextResp(gtpc_ud.peer, '12345678'O, seq_nr, ctx_rsp));
3862
3863 /* TODO: Security Functions (auth/ciphering?) */
3864
3865 /* The SGSN ACKs */
3866 T.start(2.0);
3867 alt {
3868 [] GTP.receive(tr_GTPC_SGSNContextAck) -> value gtpc_ud {
3869 log("Rx SGSN Context ACK from SGSN");
3870 setverdict(pass);
3871 T.stop;
3872 }
3873 [] T.timeout {
3874 setverdict(fail, "Timeout waiting for SGSN Contect ACK");
3875 mtc.stop;
3876 }
3877 }
3878
3879 /* TODO: Update PDP Context Req/Resp */
3880 /* TODO: 7..10 Update Location, ISD */
3881
3882 /* RAU procedure completion */
3883 T.start(2.0);
3884 alt {
3885 [] as_routing_area_update_gb(0) {
3886 log("RAU procedure completed");
3887 setverdict(pass);
3888 T.stop;
3889 }
3890 [] BSSGP[0].receive { repeat; }
3891 [] T.timeout {
3892 setverdict(fail, "Timeout completing the RAU procedure");
3893 mtc.stop;
3894 }
3895 }
3896}
3897testcase TC_sgsn_context_req_out() runs on test_CT {
3898 var BSSGP_ConnHdlr vc_conn;
3899 f_init();
3900 f_sleep(1.0);
3901 vc_conn := f_start_handler(refers(f_TC_sgsn_context_req_out), testcasename(), g_gb, 73);
3902 vc_conn.done;
3903 f_cleanup();
3904}
3905
Harald Welte5ac31492018-02-15 20:39:13 +01003906control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003907 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003908 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003909 execute( TC_attach_umts_aka_umts_res() );
3910 execute( TC_attach_umts_aka_gsm_sres() );
arehbein3ede9e32023-02-06 21:02:53 +01003911 execute( TC_attach_timeout_after_pdp_act() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003912 execute( TC_attach_auth_id_timeout() );
3913 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003914 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003915 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003916 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003917 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003918 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003919 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003920 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003921 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003922 execute( TC_attach_closed_add_vty(), 20.0 );
3923 execute( TC_attach_check_subscriber_list(), 20.0 );
3924 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003925 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003926 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3927 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3928 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3929 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003930 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003931 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003932 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003933 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003934 execute( TC_attach_usim_resync() );
Eric Wildc555be52021-05-15 19:48:22 +02003935 execute( TC_attach_usim_a54_a54() );
3936 execute( TC_attach_usim_a54_a53() );
3937 execute( TC_attach_usim_a53_a54() );
3938 execute( TC_attach_usim_a50_a54() );
3939 execute( TC_attach_usim_a54_a50() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003940 execute( TC_detach_unknown_nopoweroff() );
3941 execute( TC_detach_unknown_poweroff() );
3942 execute( TC_detach_nopoweroff() );
3943 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003944 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003945 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003946 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003947 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003948 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003949 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003950 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003951 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003952 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003953 execute( TC_attach_restart_ctr_echo() );
3954 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003955 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003956 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3957 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003958 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003959 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003960 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003961
Harald Welte2aaac1b2019-05-02 10:02:53 +02003962 execute( TC_xid_empty_l3() );
3963 execute( TC_xid_n201u() );
3964
Harald Weltea05b8072019-04-23 22:35:05 +02003965 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003966 execute( TC_llc_sabm_dm_llgmm() );
3967 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003968
Harald Welte8e5932e2020-06-17 22:12:54 +02003969 execute( TC_suspend_nopaging() );
3970 execute( TC_suspend_resume() );
3971 execute( TC_suspend_rau() );
3972 execute( TC_paging_ps() );
3973
Philipp Maier7df55e02020-12-14 23:46:04 +01003974 execute( TC_bssgp_rim_single_report() );
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003975 execute( TC_rim_eutran_to_geran() );
Philipp Maier7df55e02020-12-14 23:46:04 +01003976
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003977 execute( TC_cell_change_different_rai_ci_attach() );
3978 execute( TC_cell_change_different_rai_ci_data() );
3979 execute( TC_cell_change_different_ci_attach() );
3980 execute( TC_cell_change_different_ci_data() );
3981
Vadim Yanitskiyacd0b392024-04-06 05:38:35 +07003982 execute( TC_sgsn_context_req_in() );
3983 execute( TC_sgsn_context_req_out() );
3984
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003985 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3986 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003987}
Harald Welte96a33b02018-02-04 10:36:22 +01003988
3989
3990
3991}