blob: 64ba9818a55c6e80ac6f3131e287032cd0dc5991 [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
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002633friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002634 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002635 var PDU_DTAP_PS_MT mt;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002636 var template (omit) OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002637
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002638 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002639 p_tmsi := g_pars.p_tmsi;
2640 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002641 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002642 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit, p_tmsi), ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002643 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002644 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2645 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2646 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002647 setverdict(pass);
2648 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002649 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2650 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 }
2654
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002655 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002656 setverdict(fail, "Unexpected RAU Reject");
2657 mtc.stop;
2658 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002659 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002660 setverdict(fail, "Unexpected RAU Reject");
2661 mtc.stop;
2662 }
2663
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002664 [is_iu(ran_index)] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
Alexander Couzens5d56f522019-09-03 12:36:18 +02002665 key_sts := ?)) {
2666 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2667 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002668 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002669 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002670 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002671 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2672 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002673 }
2674}
2675
Alexander Couzensbfda9212018-07-31 03:17:33 +02002676private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002677 /* first perform regular attach */
2678 f_TC_attach(id);
2679
2680 /* then send RAU */
2681 f_routing_area_update(g_pars.ra);
2682
2683 /* do another RAU */
2684 f_routing_area_update(g_pars.ra);
2685
2686 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2687}
2688
2689testcase TC_attach_rau_a_a() runs on test_CT {
2690 /* MS <-> SGSN: Successful Attach
2691 * MS -> SGSN: Routing Area Update Request
2692 * MS <- SGSN: Routing Area Update Accept
2693 * MS -> SGSN: Routing Area Update Request
2694 * MS <- SGSN: Routing Area Update Accept
2695 * MS -> SGSN: Detach (PowerOff)
2696 */
2697 var BSSGP_ConnHdlr vc_conn;
2698 f_init();
2699 f_sleep(1.0);
2700 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2701 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002702 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002703}
2704
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002705private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002706 f_TC_attach(id);
2707
2708 log("attach complete sending rau");
2709 f_routing_area_update(g_pars.ra, 0);
2710
2711 log("rau complete unregistering");
2712 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002713 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002714
2715 log("sending second RAU via different RA");
2716 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2717
2718 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2719}
2720
2721testcase TC_attach_rau_a_b() runs on test_CT {
2722 /* MS <-> SGSN: Successful Attach
2723 * MS -> SGSN: Routing Area _a_ Update Request
2724 * MS <- SGSN: Routing Area _a_ Update Accept
2725 * MS -> SGSN: Routing Area _b_ Update Request
2726 * MS <- SGSN: Routing Area _b_ Update Accept
2727 * MS -> SGSN: Detach (PowerOff)
2728 */
2729 var BSSGP_ConnHdlr vc_conn;
2730 f_init();
2731 f_sleep(1.0);
2732 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2733 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002734 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002735}
2736
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002737private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2738 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002739 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002740 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002741 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002742
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002743 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002744
2745 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002746 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002747 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2748 mtc.stop;
2749 }
Harald Welte955aa942019-05-03 01:29:29 +02002750 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002751 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002752 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002753 repeat;
2754 }
Harald Welte955aa942019-05-03 01:29:29 +02002755 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002756 /* send out a second GMM_Attach Request.
2757 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2758 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002759 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002760 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002761 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002762 }
2763 }
2764 f_sleep(1.0);
2765
2766 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2767 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002768 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002769 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002770 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002771 repeat;
2772 }
Harald Welte955aa942019-05-03 01:29:29 +02002773 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002774 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2775 mtc.stop;
2776 }
Harald Welte955aa942019-05-03 01:29:29 +02002777 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002778 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2779 mtc.stop;
2780 }
Harald Welte955aa942019-05-03 01:29:29 +02002781 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2782 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002783 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002784 setverdict(pass);
2785 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2786 }
2787 }
2788}
2789
2790testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2791 /* Testing if the SGSN ignore Attach Request with the exact same content */
2792 /* MS -> SGSN: Attach Request IMSI
2793 * MS <- SGSN: Identity Request IMSI (optional)
2794 * MS -> SGSN: Identity Response IMSI (optional)
2795 * MS <- SGSN: Identity Request IMEI
2796 * MS -> SGSN: Attach Request (2nd)
2797 * MS <- SGSN: Identity Response IMEI
2798 * MS <- SGSN: Attach Accept
2799 * MS -> SGSN: Attach Complete
2800 */
2801 var BSSGP_ConnHdlr vc_conn;
2802 f_init();
2803 f_sleep(1.0);
2804 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2805 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2806 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002807 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002808}
2809
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002810private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002811 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2812
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002813 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 +02002814
2815 /* send Attach Request */
2816 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2817 * 3G auth vectors */
2818 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2819 /* The thing is, if the solSACapability is 'omit', then the
2820 * revisionLevelIndicatior is at the wrong place! */
2821 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002822 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002823
2824 /* do the auth */
2825 var PDU_L3_MS_SGSN l3_mo;
2826 var PDU_L3_SGSN_MS l3_mt;
2827 var default di := activate(as_mm_identity());
2828
2829 var GSUP_IE auth_tuple;
2830 var template AuthenticationParameterAUTNTLV autn;
2831
2832 g_pars.vec := f_gen_auth_vec_3g();
2833 autn := {
2834 elementIdentifier := '28'O,
2835 lengthIndicator := lengthof(g_pars.vec.autn),
2836 autnValue := g_pars.vec.autn
2837 };
2838 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2839 g_pars.vec.sres,
2840 g_pars.vec.kc,
2841 g_pars.vec.ik,
2842 g_pars.vec.ck,
2843 g_pars.vec.autn,
2844 g_pars.vec.res));
2845 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2846 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2847 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2848
2849 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2850 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002851 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002852
2853 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002854 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002855
2856 /* wait for the GSUP resync request */
2857 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2858 g_pars.imsi,
2859 g_pars.vec.auts,
2860 g_pars.vec.rand));
2861
2862 /* generate new key material */
2863 g_pars.vec := f_gen_auth_vec_3g();
2864 autn := {
2865 elementIdentifier := '28'O,
2866 lengthIndicator := lengthof(g_pars.vec.autn),
2867 autnValue := g_pars.vec.autn
2868 };
2869
2870 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2871 g_pars.vec.sres,
2872 g_pars.vec.kc,
2873 g_pars.vec.ik,
2874 g_pars.vec.ck,
2875 g_pars.vec.autn,
2876 g_pars.vec.res));
2877 /* send new key material */
2878 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2879
2880 /* wait for the new Auth Request */
2881 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2882 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002883 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002884 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002885 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 +02002886 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2887 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2888 valueField := substr(g_pars.vec.res, 0, 4)
2889 };
2890 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2891 elementIdentifier := '21'O,
2892 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2893 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2894 };
2895 l3_mo := valueof(auth_ciph_resp);
2896 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2897 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2898 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2899 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2900 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002901 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002902 deactivate(di);
2903
2904 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07002905 as_gmm_gsup_lu_isd();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002906
Harald Welte955aa942019-05-03 01:29:29 +02002907 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2908 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002909 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002910 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002911 setverdict(pass);
2912}
2913
2914testcase TC_attach_usim_resync() runs on test_CT {
2915 /* MS -> SGSN: Attach Request
2916 * MS <- SGSN: Identity Request IMSI
2917 * MS -> SGSN: Identity Response IMSI
2918 * MS <- SGSN: Identity Request IMEI
2919 * MS -> SGSN: Identity Response IMEI
2920 * HLR<- SGSN: SAI Request
2921 * HLR-> SGSN: SAI Response
2922 * MS <- SGSN: Auth Request
2923 * MS -> SGSN: Auth Failure (with AUTS)
2924 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2925 * HLR-> SGSN: SAI Response (new key material)
2926 * MS <- SGSN: Auth Request (new key material)
2927 * MS -> SGSN: Auth Response
2928 * MS <- SGSN: Attach Accept
2929 * MS -> SGSN: Attach Complete
2930 */
2931 var BSSGP_ConnHdlr vc_conn;
2932 f_init();
2933 f_sleep(1.0);
2934 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2935 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002936 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002937}
2938
Eric Wildc555be52021-05-15 19:48:22 +02002939private function f_TC_attach_usim_crypt(OCT1 netcap_a2345, BIT3 auth_req_ciph) runs on BSSGP_ConnHdlr {
2940 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2941
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002942 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 +02002943 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.spare_octets := netcap_a2345; /* GEA2345... */
2944
2945 /* send Attach Request */
2946 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2947 * 3G auth vectors */
2948 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2949 /* The thing is, if the solSACapability is 'omit', then the
2950 * revisionLevelIndicatior is at the wrong place! */
2951 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2952 f_send_l3(attach_req);
2953
2954 /* do the auth */
2955 var PDU_L3_MS_SGSN l3_mo;
2956 var PDU_L3_SGSN_MS l3_mt;
2957 var default di := activate(as_mm_identity());
2958
2959 var GSUP_IE auth_tuple;
2960 var template AuthenticationParameterAUTNTLV autn;
2961
2962 g_pars.vec := f_gen_auth_vec_3g();
2963 autn := {
2964 elementIdentifier := '28'O,
2965 lengthIndicator := lengthof(g_pars.vec.autn),
2966 autnValue := g_pars.vec.autn
2967 };
2968 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2969 g_pars.vec.sres,
2970 g_pars.vec.kc,
2971 g_pars.vec.ik,
2972 g_pars.vec.ck,
2973 g_pars.vec.autn,
2974 g_pars.vec.res));
2975 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2976 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2977 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2978
2979 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand, auth_req_ciph);
2980 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2981 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
2982
2983 setverdict(pass);
2984 deactivate(di);
2985}
2986
2987private function f_TC_attach_usim_a54_a54(charstring id) runs on BSSGP_ConnHdlr {
2988 f_TC_attach_usim_crypt('10'O, '100'B);
2989}
2990
2991private function f_TC_attach_usim_a54_a53(charstring id) runs on BSSGP_ConnHdlr {
2992 f_TC_attach_usim_crypt('20'O, '011'B);
2993}
2994
2995private function f_TC_attach_usim_a53_a54(charstring id) runs on BSSGP_ConnHdlr {
2996 f_TC_attach_usim_crypt('30'O, '011'B);
2997}
2998
2999private function f_TC_attach_usim_a50_a54(charstring id) runs on BSSGP_ConnHdlr {
3000 f_TC_attach_usim_crypt('30'O, '000'B);
3001}
3002
3003private function f_TC_attach_usim_a54_a50(charstring id) runs on BSSGP_ConnHdlr {
3004 f_TC_attach_usim_crypt('00'O, '000'B);
3005}
3006
3007testcase TC_attach_usim_a54_a54() runs on test_CT {
3008 var BSSGP_ConnHdlr vc_conn;
3009 f_init();
3010 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003011 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003012 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a54), testcasename(), g_gb, 40);
3013 vc_conn.done;
3014 f_cleanup();
3015}
3016
3017testcase TC_attach_usim_a54_a53() runs on test_CT {
3018 var BSSGP_ConnHdlr vc_conn;
3019 f_init();
3020 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003021 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003022 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a53), testcasename(), g_gb, 40);
3023 vc_conn.done;
3024 f_cleanup();
3025}
3026
3027testcase TC_attach_usim_a53_a54() runs on test_CT {
3028 var BSSGP_ConnHdlr vc_conn;
3029 f_init();
3030 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003031 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3");
Eric Wildc555be52021-05-15 19:48:22 +02003032 vc_conn := f_start_handler(refers(f_TC_attach_usim_a53_a54), testcasename(), g_gb, 40);
3033 vc_conn.done;
3034 f_cleanup();
3035}
3036
3037testcase TC_attach_usim_a50_a54() runs on test_CT {
3038 var BSSGP_ConnHdlr vc_conn;
3039 f_init();
3040 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003041 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0");
Eric Wildc555be52021-05-15 19:48:22 +02003042 vc_conn := f_start_handler(refers(f_TC_attach_usim_a50_a54), testcasename(), g_gb, 40);
3043 vc_conn.done;
3044 f_cleanup();
3045}
3046
3047testcase TC_attach_usim_a54_a50() runs on test_CT {
3048 var BSSGP_ConnHdlr vc_conn;
3049 f_init();
3050 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003051 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003052 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a50), testcasename(), g_gb, 40);
3053 vc_conn.done;
3054 f_cleanup();
3055}
Harald Weltea05b8072019-04-23 22:35:05 +02003056
3057/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
3058private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
3059 f_gmm_attach(false, false);
3060 f_sleep(1.0);
3061 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
3062 /* try to detach to check if SGSN is still alive */
3063 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
3064}
3065testcase TC_llc_null() runs on test_CT {
3066 var BSSGP_ConnHdlr vc_conn;
3067 f_init();
3068 f_sleep(1.0);
3069 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
3070 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003071 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02003072}
3073
Harald Welte645a1512019-04-23 23:18:23 +02003074/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3075private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
3076 f_gmm_attach(false, false);
3077 f_sleep(1.0);
3078 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003079 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003080 setverdict(pass);
3081}
3082testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
3083 var BSSGP_ConnHdlr vc_conn;
3084 f_init();
3085 f_sleep(1.0);
3086 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
3087 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003088 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003089}
3090
3091/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3092private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
3093 f_gmm_attach(false, false);
3094 f_sleep(1.0);
3095 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003096 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003097 setverdict(pass);
3098}
3099testcase TC_llc_sabm_dm_ll5() runs on test_CT {
3100 var BSSGP_ConnHdlr vc_conn;
3101 f_init();
3102 f_sleep(1.0);
3103 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
3104 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003105 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003106}
3107
Harald Welte2aaac1b2019-05-02 10:02:53 +02003108/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
3109private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
3110 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3111 var template (value) XID_Information xid;
3112 var template XID_Information xid_rx;
3113
3114 /* first perform regular attach */
3115 f_TC_attach(id);
3116 /* then activate PDP context */
3117 f_pdp_ctx_act(apars);
3118
3119 /* start MO XID */
3120 xid := { ts_XID_L3(''O) };
3121 xid_rx := { tr_XID_L3(''O) };
3122 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3123 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003124 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003125 [] as_xid(apars);
3126 }
3127 setverdict(pass);
3128}
3129testcase TC_xid_empty_l3() runs on test_CT {
3130 var BSSGP_ConnHdlr vc_conn;
3131 f_init();
3132 f_sleep(1.0);
3133 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
3134 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003135 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003136}
3137
3138private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
3139 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3140 var template (value) XID_Information xid;
3141 var template XID_Information xid_rx;
3142
3143 /* first perform regular attach */
3144 f_TC_attach(id);
3145 /* then activate PDP context */
3146 f_pdp_ctx_act(apars);
3147
3148 /* start MO XID */
3149 xid := { ts_XID_N201U(1234) };
3150 xid_rx := { tr_XID_N201U(1234) };
3151 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3152 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003153 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003154 [] as_xid(apars);
3155 }
3156 setverdict(pass);
3157}
3158testcase TC_xid_n201u() runs on test_CT {
3159 var BSSGP_ConnHdlr vc_conn;
3160 f_init();
3161 f_sleep(1.0);
3162 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
3163 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003164 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003165}
3166
Alexander Couzens6bee0872019-05-11 01:48:50 +02003167private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
3168 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3169
3170 /* first perform regular attach */
3171 f_TC_attach(id);
3172 /* then activate PDP context */
3173 f_pdp_ctx_act(apars);
3174 /* do a normal detach */
3175 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
3176}
3177
3178testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
3179 /* MS -> SGSN: Attach Request
3180 * MS <-> SGSN: [..]
3181 * MS -> SGSN: Attach Complete
3182 * MS -> SGSN: PDP Activate Request
3183 * MS <- SGSN: PDP Activate Accept
3184 * MS -> SGSN: GMM Detach Request
3185 * MS <- SGSN: GMM Detach Accept
3186 */
3187 var BSSGP_ConnHdlr vc_conn;
3188 f_init();
3189 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
3190 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003191 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02003192}
Harald Welte645a1512019-04-23 23:18:23 +02003193
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003194private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
3195 var RoutingAreaIdentificationV old_ra := f_random_RAI();
3196 var RoutingAreaIdentificationV new_ra := f_random_RAI();
3197 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003198 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 +01003199 var PDU_L3_SGSN_MS l3_mt;
3200
3201 f_send_l3(attach_req, 0);
3202
3203 BSSGP[0].receive(tr_GMM_ID_REQ(?));
3204
3205 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
3206 alt {
3207 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
3208 setverdict(pass);
3209 }
3210 [] BSSGP[0].receive { repeat; }
3211 }
3212}
3213
3214/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
3215 * See OS#3957 and OS#4245 for more information.
3216 */
3217testcase TC_attach_req_id_req_ra_update() runs on test_CT {
3218 /*
3219 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
3220 * MS <-- SGSN: Identity Request (IMEI)
3221 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
3222 */
3223 var BSSGP_ConnHdlr vc_conn;
3224 f_init();
3225 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
3226 vc_conn.done;
3227 f_cleanup();
3228}
3229
Harald Welte8e5932e2020-06-17 22:12:54 +02003230private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
3231var PDU_BSSGP rx;
3232[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
3233 setverdict(fail, "Received unexpected PS PAGING: ", rx);
3234 mtc.stop;
3235 }
3236}
3237
3238/* SUSPEND, then DL traffic: should not pass + no paging expected */
3239private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3240 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3241 var default d;
3242
3243 /* first perform regular attach */
3244 f_TC_attach(id);
3245 /* then activate PDP context */
3246 f_pdp_ctx_act(apars);
3247 /* then transceive a downlink PDU */
3248 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3249
3250 /* now suspend GPRS */
3251 f_bssgp_suspend();
3252
3253 d := activate(as_nopaging_ps());
3254
3255 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3256 * nor any related paging requests */
3257 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3258
3259 deactivate(d);
3260}
3261testcase TC_suspend_nopaging() runs on test_CT {
3262 var BSSGP_ConnHdlr vc_conn;
3263 f_init();
3264 f_sleep(1.0);
3265 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3266 vc_conn.done;
3267 f_cleanup();
3268}
3269
3270
3271/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3272private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3273 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3274 var OCT1 susp_ref;
3275 var default d;
3276
3277 /* first perform regular attach */
3278 f_TC_attach(id);
3279 /* then activate PDP context */
3280 f_pdp_ctx_act(apars);
3281 /* then transceive a downlink PDU */
3282 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3283
3284 /* now suspend GPRS */
3285 susp_ref := f_bssgp_suspend();
3286
3287 d := activate(as_nopaging_ps());
3288
3289 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3290 * nor any related paging requests */
3291 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3292
3293 deactivate(d);
3294
3295 /* resume GPRS */
3296 f_bssgp_resume(susp_ref);
3297
3298 /* now data should be flowing again */
3299 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3300}
3301testcase TC_suspend_resume() runs on test_CT {
3302 var BSSGP_ConnHdlr vc_conn;
3303 f_init();
3304 f_sleep(1.0);
3305 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3306 vc_conn.done;
3307 f_cleanup();
3308}
3309
3310/* SUSPEND, then RAU: data expected to flow after implicit resume */
3311private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3312 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3313 var default d;
3314
3315 /* first perform regular attach */
3316 f_TC_attach(id);
3317 /* then activate PDP context */
3318 f_pdp_ctx_act(apars);
3319 /* then transceive a downlink PDU */
3320 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3321
3322 /* now suspend GPRS */
3323 f_bssgp_suspend();
3324
3325 d := activate(as_nopaging_ps());
3326
3327 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3328 * nor any related paging requests */
3329 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3330
3331 deactivate(d);
3332
3333 /* perform RAU (implicit RESUME) */
3334 f_routing_area_update(g_pars.ra);
3335
Harald Welted5836dc2021-03-20 15:40:00 +01003336 /* give SGSN some time to actually receve + process the RAU Complete we sent */
3337 f_sleep(0.5);
3338
Harald Welte8e5932e2020-06-17 22:12:54 +02003339 /* now data should be flowing again */
3340 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3341
3342}
3343testcase TC_suspend_rau() runs on test_CT {
3344 var BSSGP_ConnHdlr vc_conn;
3345 f_init();
3346 f_sleep(1.0);
3347 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3348 vc_conn.done;
3349 f_cleanup();
3350}
3351
3352
3353/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3354private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3355 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3356 var default d;
3357
3358 /* first perform regular attach */
3359 f_TC_attach(id);
3360 /* then activate PDP context */
3361 f_pdp_ctx_act(apars);
3362 /* then transceive a downlink PDU */
3363 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3364
3365 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3366 f_sleep(5.0);
3367
3368 /* now data should be flowing again, but with PS PAGING */
3369 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3370 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3371
3372 /* FIXME: simulate paging response */
3373 /* FIXME: verify PDU actually arrives only after paging response was successful */
3374
3375}
3376testcase TC_paging_ps() runs on test_CT {
3377 var BSSGP_ConnHdlr vc_conn;
3378 f_init();
3379 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3380 f_sleep(1.0);
3381 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3382 vc_conn.done;
3383 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3384 f_cleanup();
3385}
3386
Philipp Maier7df55e02020-12-14 23:46:04 +01003387/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3388 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3389 * other and vice versa. */
3390testcase TC_bssgp_rim_single_report() runs on test_CT {
3391 var BSSGP_ConnHdlr vc_conn;
3392 f_init();
Philipp Maier7df55e02020-12-14 23:46:04 +01003393
3394 timer T := 2.0;
3395
3396 var template RIM_Routing_Address dst_addr;
3397 var template RIM_Routing_Address src_addr;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003398 var template (value) RAN_Information_Request_RIM_Container req_cont;
3399 var template (value) RAN_Information_RIM_Container res_cont;
3400 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maier7df55e02020-12-14 23:46:04 +01003401 var template PDU_BSSGP bssgp_rim_pdu_expect;
3402
3403 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3404 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003405
3406
Philipp Maier7df55e02020-12-14 23:46:04 +01003407 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3408 * based on the cell id in dst_addr to GB interface #1. */
3409 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3410 ts_RIM_Sequence_Number(1),
3411 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3412 ts_RIM_Protocol_Version_Number(1),
3413 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3414 omit);
3415 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3416 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3417 req_cont);
3418 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3419 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3420 tr_RAN_Information_Request_RIM_Container);
3421 RIM[0].send(bssgp_rim_pdu);
3422 T.start;
3423 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003424 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3425 setverdict(pass);
3426 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003427 [] RIM[1].receive {
3428 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003429 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003430 [] T.timeout {
3431 setverdict(fail, "No BSSGP RIM PDU received");
3432 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003433 }
3434 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003435
Philipp Maier7df55e02020-12-14 23:46:04 +01003436 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3437 * GB interface #0 */
Philipp Maier7df55e02020-12-14 23:46:04 +01003438 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3439 ts_RIM_Sequence_Number(2),
3440 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3441 ts_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003442 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 +01003443 omit);
3444 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3445 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3446 res_cont);
3447 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3448 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3449 ?);
3450 RIM[1].send(bssgp_rim_pdu);
3451 T.start;
3452 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003453 [] RIM[0].receive(bssgp_rim_pdu_expect) {
3454 setverdict(pass);
3455 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003456 [] RIM[0].receive {
3457 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003458 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003459 [] T.timeout {
3460 setverdict(fail, "No BSSGP RIM PDU received");
3461 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003462 }
3463 }
3464
3465 f_cleanup();
3466}
Harald Welte8e5932e2020-06-17 22:12:54 +02003467
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003468testcase TC_rim_eutran_to_geran() runs on test_CT {
3469 var BSSGP_ConnHdlr vc_conn;
3470 f_init();
3471 /* connect RIM related port */
3472 connect(vc_GTP:CLIENT_DEFAULT, self:GTPC);
3473
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01003474 var Gtp1cPeer peer := {
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003475 connId := 1,
3476 remName := mp_sgsn_gtp_ip,
3477 remPort := GTP1C_PORT
3478 }
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003479 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 +02003480
3481 var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
3482 var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
3483 var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
Philipp Maier7e9acc32023-08-04 17:23:12 +02003484 var template (value) RIM_RoutingAddress gtpc_rim_ra;
3485 var template (value) RIM_RoutingAddress_Discriminator gtpc_rim_ra_discr;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003486 var template (value) Gtp1cUnitdata gtpc_pdu;
3487
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003488 gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(gtp_ci);
3489 gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(gtp_ci, tac := 3, gnbid := '12345678123456'O);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003490
3491 gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3492 ts_GTPC_RIM_Sequence_Number(1),
3493 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3494 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003495 tsu_GTPC_RAN_Information_Request_Application_Container_NACC(gtp_ci),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003496 omit);
3497 gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3498 ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3499 gtpc_rim_req_cont);
Philipp Maier7e9acc32023-08-04 17:23:12 +02003500
3501 /* Assemble RIM Routing Address (essentially a copy of the destination cell identifier)*/
3502 gtpc_rim_ra := ts_RIM_RoutingAddress(enc_RIM_Routing_Address_GTPC(valueof(gtpc_dst_addr)));
3503 gtpc_rim_ra_discr := ts_RIM_RoutingAddress_Discriminator(hex2bit(RIM_ADDR_GERAN_CELL_ID));
3504 gtpc_pdu := ts_GTPC_RANInfoRelay(peer, ts_RANTransparentContainer_RAN_INFO_REQ(gtpc_bssgp_cont),
3505 gtpc_rim_ra, gtpc_rim_ra_discr);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003506 GTPC.send(gtpc_pdu);
3507
3508 var template RIM_Routing_Address bssgp_dst_addr, bssgp_src_addr;
3509 var template PDU_BSSGP bssgp_rim_pdu_expect;
3510 bssgp_dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3511 bssgp_src_addr := t_RIM_Routing_Address_enbid(g_gb[1].cfg.bvc[0].cell_id, tac := 3, gnbid := '12345678123456'O);
3512 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3513 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3514 tr_RAN_Information_Request_RIM_Container);
3515 timer T := 2.0;
3516 T.start;
3517 alt {
3518 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3519 setverdict(pass);
3520 T.stop;
3521 }
3522 [] RIM[1].receive {
3523 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3524 }
3525 [] T.timeout {
3526 setverdict(fail, "No BSSGP RIM PDU received");
3527 mtc.stop;
3528 }
3529 }
3530
3531 /* Now also emulate also the response as well and send it back on GB
3532 interface #1. Expect the result on * GTPC */
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003533 var template (value) RAN_Information_RIM_Container res_cont;
3534 var template (value) PDU_BSSGP bssgp_rim_pdu;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003535 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3536 ts_RIM_Sequence_Number(2),
3537 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3538 ts_RIM_Protocol_Version_Number(1),
3539 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[1].cfg.bvc[0].cell_id, false, 3, si_default)),
3540 omit);
3541 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3542 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3543 res_cont);
3544 RIM[1].send(bssgp_rim_pdu);
3545
3546 var template RAN_Information_RIM_Container_GTPC rim_cont;
3547 var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_cont_ack;
3548 var template Gtp1cUnitdata gtpc_pdu_exp;
3549 rim_cont := tr_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3550 ts_GTPC_RIM_Sequence_Number(2),
3551 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3552 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003553 tru_GTPC_ApplContainer_or_ApplErrContainer_NACC(tru_GTPC_ApplContainer_NACC(gtp_ci, false, 3, si_default)),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003554 omit);
3555 gtpc_bssgp_cont_ack := tr_GTPC_RAN_Information(tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3556 tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3557 rim_cont);
3558 gtpc_pdu_exp := tr_GTPC_RANInfoRelay(peer, tr_RANTransparentContainer_RAN_INFO(gtpc_bssgp_cont_ack));
3559
3560 T.start;
3561 alt {
3562 [] GTPC.receive(gtpc_pdu_exp) {
3563 setverdict(pass);
3564 T.stop;
3565 }
3566 [] GTPC.receive {
3567 setverdict(fail, "Unexpected GTPC RIM PDU received");
3568 }
3569 [] T.timeout {
3570 setverdict(fail, "No GTPC RIM PDU received");
3571 mtc.stop;
3572 }
3573 }
3574
3575 f_cleanup();
3576}
3577
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003578/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3579private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3580 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3581
3582 /* first perform regular attach */
3583 f_gmm_attach(false, false, ran_index := 0);
3584 /* then activate PDP context */
3585 f_pdp_ctx_act(apars, ran_index := 0);
3586 /* then transceive a downlink PDU */
3587 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3588 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3589
3590 /* Now attach on different cell: */
3591 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3592 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3593 g_pars.net.expect_auth := false;
3594 f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0]));
3595 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3596 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1);
3597}
3598testcase TC_cell_change_different_rai_ci_attach() runs on test_CT {
3599 var BSSGP_ConnHdlr vc_conn;
3600 f_init();
3601 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68);
3602 vc_conn.done;
3603 f_cleanup();
3604}
3605
3606/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3607/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3608private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3609 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3610
3611 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3612 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3613
3614 /* first perform regular attach */
3615 f_gmm_attach(false, false, ran_index := 1);
3616 /* then activate PDP context */
3617 f_pdp_ctx_act(apars, ran_index := 1);
3618 /* then transceive a downlink PDU */
3619 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3620 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3621
3622 /* Now attach on different cell: */
3623 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3624 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3625 g_pars.net.expect_auth := false;
3626 f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1]));
3627 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3628 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3629}
3630testcase TC_cell_change_different_ci_attach() runs on test_CT {
3631 var BSSGP_ConnHdlr vc_conn;
3632 f_init();
3633 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69);
3634 vc_conn.done;
3635 f_cleanup();
3636}
3637
3638/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */
3639private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3640 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3641
3642 /* first perform regular attach */
3643 f_gmm_attach(false, false, ran_index := 0);
3644 /* then activate PDP context */
3645 f_pdp_ctx_act(apars, ran_index := 0);
3646 /* then transceive a downlink PDU */
3647 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3648 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3649
3650 /* Send some data over new bvci, it should be silently discarded since
3651 * RAC changed and SGSN expects a RAU to occur in that case */
3652 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3653 var octetstring payload := f_rnd_octstring(200);
3654 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
3655 BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1));
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01003656 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003657 timer T := 2.0;
3658 T.start;
3659 alt {
3660 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) {
3661 setverdict(fail, "Unexpected GTP message");
3662 }
3663 [] T.timeout { setverdict(pass); }
3664 }
3665
3666 /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */
3667 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3668 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3669}
3670testcase TC_cell_change_different_rai_ci_data() runs on test_CT {
3671 var BSSGP_ConnHdlr vc_conn;
3672 f_init();
3673 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70);
3674 vc_conn.done;
3675 f_cleanup();
3676}
3677
3678/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */
3679/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3680private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3681 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3682
3683 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3684 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3685
3686 /* first perform regular attach */
3687 f_gmm_attach(false, false, ran_index := 1);
3688 /* then activate PDP context */
3689 f_pdp_ctx_act(apars, ran_index := 1);
3690 /* then transceive a downlink PDU */
3691 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3692 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3693
3694 /* Now attach on different cell: */
3695 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3696 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3697
3698 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3699 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3700}
3701testcase TC_cell_change_different_ci_data() runs on test_CT {
3702 var BSSGP_ConnHdlr vc_conn;
3703 f_init();
3704 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71);
3705 vc_conn.done;
3706 f_cleanup();
3707}
3708
Harald Welte5ac31492018-02-15 20:39:13 +01003709control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003710 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003711 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003712 execute( TC_attach_umts_aka_umts_res() );
3713 execute( TC_attach_umts_aka_gsm_sres() );
arehbein3ede9e32023-02-06 21:02:53 +01003714 execute( TC_attach_timeout_after_pdp_act() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003715 execute( TC_attach_auth_id_timeout() );
3716 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003717 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003718 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003719 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003720 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003721 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003722 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003723 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003724 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003725 execute( TC_attach_closed_add_vty(), 20.0 );
3726 execute( TC_attach_check_subscriber_list(), 20.0 );
3727 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003728 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003729 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3730 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3731 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3732 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003733 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003734 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003735 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003736 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003737 execute( TC_attach_usim_resync() );
Eric Wildc555be52021-05-15 19:48:22 +02003738 execute( TC_attach_usim_a54_a54() );
3739 execute( TC_attach_usim_a54_a53() );
3740 execute( TC_attach_usim_a53_a54() );
3741 execute( TC_attach_usim_a50_a54() );
3742 execute( TC_attach_usim_a54_a50() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003743 execute( TC_detach_unknown_nopoweroff() );
3744 execute( TC_detach_unknown_poweroff() );
3745 execute( TC_detach_nopoweroff() );
3746 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003747 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003748 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003749 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003750 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003751 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003752 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003753 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003754 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003755 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003756 execute( TC_attach_restart_ctr_echo() );
3757 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003758 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003759 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3760 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003761 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003762 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003763 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003764
Harald Welte2aaac1b2019-05-02 10:02:53 +02003765 execute( TC_xid_empty_l3() );
3766 execute( TC_xid_n201u() );
3767
Harald Weltea05b8072019-04-23 22:35:05 +02003768 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003769 execute( TC_llc_sabm_dm_llgmm() );
3770 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003771
Harald Welte8e5932e2020-06-17 22:12:54 +02003772 execute( TC_suspend_nopaging() );
3773 execute( TC_suspend_resume() );
3774 execute( TC_suspend_rau() );
3775 execute( TC_paging_ps() );
3776
Philipp Maier7df55e02020-12-14 23:46:04 +01003777 execute( TC_bssgp_rim_single_report() );
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003778 execute( TC_rim_eutran_to_geran() );
Philipp Maier7df55e02020-12-14 23:46:04 +01003779
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003780 execute( TC_cell_change_different_rai_ci_attach() );
3781 execute( TC_cell_change_different_rai_ci_data() );
3782 execute( TC_cell_change_different_ci_attach() );
3783 execute( TC_cell_change_different_ci_data() );
3784
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003785 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3786 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003787}
Harald Welte96a33b02018-02-04 10:36:22 +01003788
3789
3790
3791}