blob: 9c7383425387fb7fa51e53951947930d4101d5ef [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 };
Vadim Yanitskiy96c6afa2024-05-15 01:37:36 +0500617 var RANAP_IEs.RAC rac := '00'O;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200618 var SAI sai := {
619 pLMNidentity := lai.pLMNidentity,
620 lAC := lai.lAC,
621 sAC := '0000'O, /* FIXME */
622 iE_Extensions := omit
623 };
624 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
625 var GlobalRNC_ID grnc_id := {
626 pLMNidentity := lai.pLMNidentity,
627 rNC_ID := 2342 /* FIXME */
628 };
629
Vadim Yanitskiy96c6afa2024-05-15 01:37:36 +0500630 ranap := valueof(ts_RANAP_initialUE_PS(lai, rac, sai, l3_enc, sigc_id, grnc_id));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200631 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
632 alt {
633 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
634 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
635 setverdict(fail, "DISC.ind from SCCP");
636 mtc.stop;
637 }
638 }
639}
640
641/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200642function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
643 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200644 if (g_pars.rnc_send_initial_ue) {
645 g_pars.rnc_send_initial_ue := false;
646 f_send_l3_initial_ue(l3_mo);
647 } else {
648 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
649 }
650 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200651 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200652 }
653}
654
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200655altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700656 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200657 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100658 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200659 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100660 repeat;
661 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200662 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200663 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200664 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200665 repeat;
666 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200667 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100668 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200669 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200670 repeat;
671 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200672 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200673 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200674 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100675 repeat;
676 }
677}
Harald Welte96a33b02018-02-04 10:36:22 +0100678
Harald Welteca362462019-05-02 20:11:21 +0200679/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200680function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200681runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200682 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200683 var PDU_L3_SGSN_MS l3_mt;
684 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200685 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
686 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200687 l3_mt := mt.dtap;
688 }
Harald Welteca362462019-05-02 20:11:21 +0200689 }
690 return l3_mt;
691}
692
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100693/* (copied from msc/BSC_ConnectionHandler.ttcn) */
694private altstep as_ciph_utran() runs on BSSGP_ConnHdlr
695{
696 [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(uia_algs := ?,
697 uia_key := oct2bit(g_pars.vec.ik),
698 key_sts := ?,
699 uea_algs := ?,
700 uea_key := oct2bit(g_pars.vec.ck))) {
701 var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1*/
702 var EncryptionAlgorithm uea_chosen := 1; /*standard_UMTS_encryption_algorith_UEA1*/
703 BSSAP.send(ts_RANAP_SecurityModeCompleteEnc(uia_chosen, uea_chosen));
704 }
705 [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(?,?,?,?,?)) {
706 setverdict(fail, "Invalid SecurityModeCommand (ciphering case)");
707 mtc.stop;
708 }
709 [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?,
710 uia_key := oct2bit(g_pars.vec.ik),
711 key_sts := ?)) {
712 var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1;*/
713 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
714 }
715 [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(?,?,?)) {
716 setverdict(fail, "Invalid SecurityModeCommand (non-ciphering case)");
717 mtc.stop;
718 }
719}
720
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200721/* perform GMM authentication (if expected).
722 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
723 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200724function 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 +0100725 var PDU_L3_MS_SGSN l3_mo;
726 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200727 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100728 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200729 var GSUP_IE auth_tuple;
730 var template AuthenticationParameterAUTNTLV autn;
731
732 if (umts_aka_challenge) {
733 g_pars.vec := f_gen_auth_vec_3g();
734 autn := {
735 elementIdentifier := '28'O,
736 lengthIndicator := lengthof(g_pars.vec.autn),
737 autnValue := g_pars.vec.autn
738 };
739
740 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
741 g_pars.vec.sres,
742 g_pars.vec.kc,
743 g_pars.vec.ik,
744 g_pars.vec.ck,
745 g_pars.vec.autn,
746 g_pars.vec.res));
747 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
748 } else {
749 g_pars.vec := f_gen_auth_vec_2g();
750 autn := omit;
751 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
752 g_pars.vec.sres,
753 g_pars.vec.kc));
754 log("GSUP sends only 2G auth tuple", auth_tuple);
755 }
Harald Welteca362462019-05-02 20:11:21 +0200756
Harald Welte5ac31492018-02-15 20:39:13 +0100757 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
758 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200759
760 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
761 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200762 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100763 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +0700764 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 +0200765
766 if (umts_aka_challenge and not force_gsm_sres) {
767 /* set UMTS response instead */
768 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
769 valueField := substr(g_pars.vec.res, 0, 4)
770 };
771 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
772 elementIdentifier := '21'O,
773 lengthIndicator := lengthof(g_pars.vec.res) - 4,
774 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
775 };
776 }
777
778 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100779 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
780 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
781 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
782 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
783 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200784 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200785
786 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200787 if (is_iu(ran_index)) {
Neels Hofmeyr3ee71d82022-03-08 21:46:41 +0100788 as_ciph_utran();
789 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200790 }
Harald Welte76dee092018-02-16 22:12:59 +0100791 } else {
792 /* wait for identity procedure */
793 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100794 }
Harald Welte76dee092018-02-16 22:12:59 +0100795
Harald Welte5ac31492018-02-15 20:39:13 +0100796 deactivate(di);
797}
798
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200799function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100800 g_pars.p_tmsi := p_tmsi;
801 /* update TLLI */
802 g_pars.tlli_old := g_pars.tlli;
803 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100804 if (is_gb(ran_index)) {
805 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
806 }
Harald Weltef70997d2018-02-17 10:11:19 +0100807}
808
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100809function f_process_attach_accept(PDU_GMM_AttachAccept aa, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100810 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100811 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Harald Weltedd9fb842021-02-16 20:21:22 +0100812 /* we cannot use ran_index here, as it would overflow the cell_id object, since ran_idx > NUM_GB
813 * indicates an Iu RAN connection. All cells are expected to run the same MCC/MNC anyway... */
814 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100815 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100816 & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200817 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100818 }
Harald Welte04683d02018-02-16 22:43:45 +0100819 g_pars.ra := aa.routingAreaIdentification;
820 if (ispresent(aa.allocatedPTMSI)) {
821 if (not g_pars.net.expect_ptmsi) {
822 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200823 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100824 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100825 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
826 ran_index);
Harald Welte04683d02018-02-16 22:43:45 +0100827 }
828 if (ispresent(aa.msIdentity)) {
829 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200830 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100831 }
832 /* P-TMSI.sig */
833 if (ispresent(aa.ptmsiSignature)) {
834 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
835 }
836 /* updateTimer */
837 // aa.readyTimer
838 /* T3302, T3319, T3323, T3312_ext, T3324 */
839}
840
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200841function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100842 /* mandatory IE */
843 g_pars.ra := ra.routingAreaId;
844 if (ispresent(ra.allocatedPTMSI)) {
845 if (not g_pars.net.expect_ptmsi) {
846 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200847 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100848 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100849 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
850 ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100851 }
852 if (ispresent(ra.msIdentity)) {
853 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200854 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100855 }
856 /* P-TMSI.sig */
857 if (ispresent(ra.ptmsiSignature)) {
858 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
859 }
860 /* updateTimer */
861 // aa.readyTimer
862 /* T3302, T3319, T3323, T3312_ext, T3324 */
863}
864
865
Harald Welte5a4fa042018-02-16 20:59:21 +0100866function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
867 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
868}
869
Harald Welte23178c52018-02-17 09:36:33 +0100870/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700871private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100872 if (ispresent(g_pars.p_tmsi)) {
873 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
874 } else {
875 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
876 }
877}
878
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700879private altstep as_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
880 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
881 var GSUP_PDU gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
Pau Espin Pedrolc63fa8e2024-01-22 19:58:09 +0100882 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo('00'O, char2oct("*"), ts_EuaIPv4Dyn, ''O)) };
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700883 GSUP.send(gsup);
884 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
885 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
886 }
Harald Welte311ec272018-02-17 09:40:03 +0100887}
888
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100889friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0,
890 template (omit) RoutingAreaIdentificationV old_ra := omit) runs on BSSGP_ConnHdlr {
891 var RoutingAreaIdentificationV old_ra_val;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +0700892 var template (value) PDU_L3_MS_SGSN attach_req;
Harald Welteca362462019-05-02 20:11:21 +0200893 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100894
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100895 if (istemplatekind(old_ra, "omit")) {
896 old_ra_val := f_random_RAI();
897 } else {
898 old_ra_val := valueof(old_ra);
899 }
900
901 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra_val, false, false, omit, omit);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200902 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
903 * 3G auth vectors */
904 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
905 /* The thing is, if the solSACapability is 'omit', then the
906 * revisionLevelIndicatior is at the wrong place! */
907 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
908
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200909 f_send_l3(attach_req, ran_index);
910 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200911 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +0700912 as_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100913
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200914 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100915 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200916
Harald Welte04683d02018-02-16 22:43:45 +0100917 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200918 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200919
920 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200921 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200922 as_iu_release_compl_disc();
923 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200924
925 /* Race condition
926 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
927 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
928 * arrived before it. This results in a test case failure.
929 * Delay execution by 50 ms
930 */
931 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200932}
933
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200934friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
935 timer T := 5.0;
936 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100937 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 +0200938 T.start;
939 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100940 [] 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 +0200941 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
942 }
Harald Welte9b461a92020-12-10 23:41:14 +0100943 [] 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 +0200944 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
945 mtc.stop;
946 }
947 [] T.timeout {
948 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
949 mtc.stop;
950 }
951 }
952 return '00'O;
953}
954
955friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
956 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100957 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 +0200958 T.start;
959 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100960 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
961 [] 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 +0200962?)) {
963 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
964 mtc.stop;
965 }
966 [] T.timeout {
967 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
968 mtc.stop;
969 }
970 }
971}
972
973
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200974private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
975 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100976 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100977}
978
979testcase TC_attach() runs on test_CT {
980 var BSSGP_ConnHdlr vc_conn;
981 f_init();
982 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200983 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100984 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200985 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100986}
987
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100988testcase TC_attach_mnc3() runs on test_CT {
989 var BSSGP_ConnHdlr vc_conn;
990 f_init('023042'H);
991 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200992 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100993 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200994 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100995}
996
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200997private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
998 f_gmm_attach(true, false);
999 setverdict(pass);
1000}
1001testcase TC_attach_umts_aka_umts_res() runs on test_CT {
1002 var BSSGP_ConnHdlr vc_conn;
1003 f_init();
1004 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001005 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001006 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001007 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001008}
1009
1010private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
1011 f_gmm_attach(true, true);
1012 setverdict(pass);
1013}
1014testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
1015 var BSSGP_ConnHdlr vc_conn;
1016 f_init();
1017 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001018 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001019 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001020 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001021}
1022
arehbein3ede9e32023-02-06 21:02:53 +01001023/* Let T3350 expire while the MS holds an active PDP context (OS#4221). Do this by
1024 * Establishing a PDP context and then resending an ATTACH REQUEST,
1025 * making sure that exactly five ATTACH ACCEPTS are sent */
1026private function f_TC_attach_timeout_after_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
1027 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1028 /* Vars needed for triggering T3350 timeouts */
1029 const integer ran_index := 0;
1030 /* See TS 24.008 Rel. 16 Sect. 4.7.3.1.6 c) */
1031 const integer gmm_attach_repeats := 5;
1032 /* See TS 24.008 Rel. 16 Table 11.4 */
1033 const float T3350 := 6.0;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07001034 var template (value) PDU_L3_MS_SGSN attach_req;
arehbein3ede9e32023-02-06 21:02:53 +01001035 timer t_receive_GMM_ATTACH_ACCEPT;
1036 var RoutingAreaIdentificationV rai := f_random_RAI();
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001037 timer T;
arehbein3ede9e32023-02-06 21:02:53 +01001038
1039 /* First establish PDP context */
1040 f_TC_attach(id);
1041 f_pdp_ctx_act(apars);
1042
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001043 /* Now, try another GPRS attach procedure. Note that osmo-sgsn does not require
1044 * authentication for the second GMM ATTACH REQUEST, so we expect GSUP UPDATE
1045 * LOCATION REQUEST and optionally a GMM IDENTITY REQUEST (IMEI). */
arehbein3ede9e32023-02-06 21:02:53 +01001046 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), rai, false, false, omit, omit);
1047 f_send_l3(attach_req, ran_index);
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001048
1049 T.start(1.0);
1050 alt {
1051 [] as_gmm_gsup_lu_isd();
1052 [] as_mm_identity(ran_index);
1053 [] as_xid(apars, ran_index);
1054 [] T.timeout {
1055 setverdict(fail, "Timeout waiting for GSUP UPDATE LOCATION REQUEST");
1056 return;
1057 }
1058 }
arehbein3ede9e32023-02-06 21:02:53 +01001059
1060 BSSGP[ran_index].clear;
1061 log("Trying to receive ", gmm_attach_repeats, " ATTACH ACCEPTs");
1062 for (var integer i := 1; i <= gmm_attach_repeats; i := i+1) {
1063 t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5);
1064 alt {
1065 [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) {
1066 t_receive_GMM_ATTACH_ACCEPT.stop;
1067 }
1068 [] t_receive_GMM_ATTACH_ACCEPT.timeout {
1069 setverdict(fail, "Timeout on receiving ", i, "th ATTACH ACCEPT")
1070 }
1071 }
1072 }
1073 log("Have received ", gmm_attach_repeats, " ATTACH ACCEPT messages");
1074 log("Make sure not more than ", gmm_attach_repeats, " ATTACH ACCEPT messages are sent");
1075 t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5);
1076 alt {
1077 [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) {
1078 setverdict(fail, "Received ", gmm_attach_repeats + 1, "th ATTACH ACCEPT")
1079 }
1080 [] t_receive_GMM_ATTACH_ACCEPT.timeout { }
1081 }
1082
1083 setverdict(pass);
1084}
1085
1086testcase TC_attach_timeout_after_pdp_act() runs on test_CT {
1087 var BSSGP_ConnHdlr vc_conn;
1088 f_init();
Vadim Yanitskiyd2f1bc92023-06-27 19:02:03 +07001089 vc_conn := f_start_handler(refers(f_TC_attach_timeout_after_pdp_act),
1090 testcasename(), g_gb, 21, t_guard := 45.0);
1091 vc_conn.done;
arehbein3ede9e32023-02-06 21:02:53 +01001092 f_cleanup();
1093}
1094
Harald Welte5b7c8122018-02-16 21:48:17 +01001095/* MS never responds to ID REQ, expect ATTACH REJECT */
1096private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001097 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1098
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001099 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001100 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001101 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001102 /* don't send ID Response */
1103 repeat;
1104 }
Harald Welte955aa942019-05-03 01:29:29 +02001105 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001106 setverdict(pass);
1107 }
Harald Welte955aa942019-05-03 01:29:29 +02001108 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001109 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +02001110 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001111 }
1112 }
1113}
1114testcase TC_attach_auth_id_timeout() runs on test_CT {
1115 var BSSGP_ConnHdlr vc_conn;
1116 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001117 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 +01001118 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001119 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001120}
1121
1122/* HLR never responds to SAI REQ, expect ATTACH REJECT */
1123private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001124 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1125
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001126 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001127 alt {
1128 [] as_mm_identity();
1129 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1130 }
1131 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001132 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001133 setverdict(pass);
1134}
1135testcase TC_attach_auth_sai_timeout() runs on test_CT {
1136 var BSSGP_ConnHdlr vc_conn;
1137 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001138 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001139 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001140 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001141}
1142
Harald Weltefe253882018-02-17 09:25:00 +01001143/* HLR rejects SAI, expect ATTACH REJECT */
1144private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001145 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1146
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001147 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001148 alt {
1149 [] as_mm_identity();
1150 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1151 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1152 }
1153 }
Harald Welte955aa942019-05-03 01:29:29 +02001154 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001155 setverdict(pass);
1156}
1157testcase TC_attach_auth_sai_reject() runs on test_CT {
1158 var BSSGP_ConnHdlr vc_conn;
1159 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001160 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001161 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001162 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001163}
1164
Harald Welte5b7c8122018-02-16 21:48:17 +01001165/* HLR never responds to UL REQ, expect ATTACH REJECT */
1166private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001167 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001168 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1169
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001170 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001171 f_gmm_auth();
1172 /* Expect MSC to perform LU with HLR */
1173 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1174 /* Never follow-up with ISD_REQ or UL_RES */
1175 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001176 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001177 setverdict(pass);
1178 }
Harald Welte955aa942019-05-03 01:29:29 +02001179 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1180 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001181 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001182 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001183 }
1184 }
1185}
1186testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1187 var BSSGP_ConnHdlr vc_conn;
1188 f_init();
1189 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001190 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001191 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001192 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001193}
1194
Harald Welteb7c14e92018-02-17 09:29:16 +01001195/* HLR rejects UL REQ, expect ATTACH REJECT */
1196private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001197 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001198 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1199
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001200 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001201 f_gmm_auth();
1202 /* Expect MSC to perform LU with HLR */
1203 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1204 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1205 }
1206 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001207 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001208 setverdict(pass);
1209 }
Harald Welte955aa942019-05-03 01:29:29 +02001210 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1211 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001212 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001213 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001214 }
1215 }
1216}
1217testcase TC_attach_gsup_lu_reject() runs on test_CT {
1218 var BSSGP_ConnHdlr vc_conn;
1219 f_init();
1220 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001221 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001222 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001223 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001224}
1225
1226
Harald Welte3823e2e2018-02-16 21:53:48 +01001227/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1228private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001229 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001230 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1231
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001232 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001233 f_gmm_auth();
1234 /* Expect MSC to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07001235 as_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001236
Harald Welte955aa942019-05-03 01:29:29 +02001237 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1238 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001239 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001240 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001241 setverdict(pass);
1242}
Harald Welte3823e2e2018-02-16 21:53:48 +01001243testcase TC_attach_combined() runs on test_CT {
1244 var BSSGP_ConnHdlr vc_conn;
1245 f_init();
1246 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001247 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001248 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001249 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001250}
1251
Harald Welte76dee092018-02-16 22:12:59 +01001252/* Attempt of GPRS ATTACH in 'accept all' mode */
1253private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001254 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001255 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1256
1257 g_pars.net.expect_auth := false;
1258
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001259 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001260 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001261 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1262 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001263 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001264 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001265 setverdict(pass);
1266}
1267testcase TC_attach_accept_all() runs on test_CT {
1268 var BSSGP_ConnHdlr vc_conn;
1269 f_init();
1270 f_sleep(1.0);
1271 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001272 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001273 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001274 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001275}
Harald Welte5b7c8122018-02-16 21:48:17 +01001276
Harald Welteb2124b22018-02-16 22:26:56 +01001277/* Attempt of GPRS ATTACH in 'accept all' mode */
1278private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001279 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1280
1281 /* Simulate a foreign IMSI */
1282 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001283 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001284
1285 g_pars.net.expect_auth := false;
1286
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001287 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001288 alt {
1289 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001290 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001291 setverdict(pass);
1292 }
Harald Welte955aa942019-05-03 01:29:29 +02001293 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001294 setverdict(pass);
1295 }
Harald Welte955aa942019-05-03 01:29:29 +02001296 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001297 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001298 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001299 }
Harald Welteb2124b22018-02-16 22:26:56 +01001300 }
1301}
1302testcase TC_attach_closed() runs on test_CT {
1303 var BSSGP_ConnHdlr vc_conn;
1304 f_init();
1305 f_sleep(1.0);
1306 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1307 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001308 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001309 vc_conn.done;
1310 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001311 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001312 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001313 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001314}
1315
Harald Welte04683d02018-02-16 22:43:45 +01001316/* Routing Area Update from Unknown TLLI -> REJECT */
1317private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001318 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1319
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001320 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 +01001321 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001322 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001323 setverdict(pass);
1324 }
1325 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001326 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001327 }
1328}
1329testcase TC_rau_unknown() runs on test_CT {
1330 var BSSGP_ConnHdlr vc_conn;
1331 f_init();
1332 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001333 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001334 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001335 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001336}
1337
Harald Welte91636de2018-02-17 10:16:14 +01001338private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001339 /* first perform regular attach */
1340 f_TC_attach(id);
1341
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001342 f_routing_area_update(g_pars.ra);
1343
Harald Welte91636de2018-02-17 10:16:14 +01001344}
1345testcase TC_attach_rau() runs on test_CT {
1346 var BSSGP_ConnHdlr vc_conn;
1347 f_init();
1348 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001349 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001350 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001351 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001352}
Harald Welte04683d02018-02-16 22:43:45 +01001353
Harald Welte6abb9fe2018-02-17 15:24:48 +01001354/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001355function 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 +02001356 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001357 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001358 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001359 if (expect_purge) {
1360 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1361 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1362 }
1363 T.start;
1364 alt {
1365 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1366 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001367 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001368 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001369 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001370 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001371 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001372 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001373 /* TODO: check if any PDP contexts are deactivated on network side? */
1374 }
1375 [power_off] T.timeout {
1376 setverdict(pass);
1377 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001378 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001379 g_pars.ra := omit;
1380 setverdict(pass);
1381 /* TODO: check if any PDP contexts are deactivated on network side? */
1382 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001383 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001384 if (power_off) {
1385 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1386 } else {
1387 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1388 }
1389 mtc.stop;
1390 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001391 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001392 }
1393}
1394
1395/* IMSI DETACH (non-power-off) for unknown TLLI */
1396private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1397 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1398}
1399testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1400 var BSSGP_ConnHdlr vc_conn;
1401 f_init();
1402 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001403 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001404 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001405 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001406}
1407
1408/* IMSI DETACH (power-off) for unknown TLLI */
1409private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1410 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1411}
1412testcase TC_detach_unknown_poweroff() runs on test_CT {
1413 var BSSGP_ConnHdlr vc_conn;
1414 f_init();
1415 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001416 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001417 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001418 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001419}
1420
1421/* IMSI DETACH (non-power-off) for known TLLI */
1422private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1423 /* first perform regular attach */
1424 f_TC_attach(id);
1425
1426 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1427}
1428testcase TC_detach_nopoweroff() runs on test_CT {
1429 var BSSGP_ConnHdlr vc_conn;
1430 f_init();
1431 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001432 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001433 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001434 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001435}
1436
1437/* IMSI DETACH (power-off) for known TLLI */
1438private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1439 /* first perform regular attach */
1440 f_TC_attach(id);
1441
1442 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1443}
1444testcase TC_detach_poweroff() runs on test_CT {
1445 var BSSGP_ConnHdlr vc_conn;
1446 f_init();
1447 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001448 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001449 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001450 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001451}
1452
Harald Welteeded9ad2018-02-17 20:57:34 +01001453type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001454 BIT3 tid, /* L3 Transaction ID */
1455 BIT4 nsapi, /* SNDCP NSAPI */
1456 BIT4 sapi, /* LLC SAPI */
1457 QoSV qos, /* QoS parameters */
1458 PDPAddressV addr, /* IP address */
1459 octetstring apn optional, /* APN name */
1460 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1461 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001462 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001463 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001464
Harald Welte822f9102018-02-18 20:39:06 +01001465 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1466 OCT4 ggsn_tei_u, /* GGSN TEI User */
1467 octetstring ggsn_ip_c, /* GGSN IP Control */
1468 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001469 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001470
Harald Welte822f9102018-02-18 20:39:06 +01001471 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1472 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1473 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1474 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001475};
1476
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001477
1478private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1479 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1480 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1481 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1482 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1483 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1484 f_gtp_register_teid(apars.ggsn_tei_c);
1485 f_gtp_register_teid(apars.ggsn_tei_u);
1486}
1487
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001488function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001489runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001490 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1491 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001492 var template Recovery_gtpc recovery := omit;
1493
1494 if (send_recovery) {
1495 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1496 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001497
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001498 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 +02001499 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001500 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1501 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1502 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1503 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1504 apars.sgsn_tei_c, apars.gtp_resp_cause,
1505 apars.ggsn_tei_c, apars.ggsn_tei_u,
1506 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001507 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1508 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001509 }
1510 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001511 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001512 setverdict(pass);
1513 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001514 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001515 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001516 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001517 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001518 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001519 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001520 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001521 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001522 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001523 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1524 mtc.stop;
1525 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001526 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001527 setverdict(pass);
1528 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001529 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001530 }
1531}
1532
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001533function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001534runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001535 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1536 var Gtp1cUnitdata g_ud;
1537
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001538 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001539 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1540 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001541 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001542 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1543 }
1544 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001545 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001546 setverdict(pass);
1547 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001548 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001549 }
1550}
1551
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001552function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001553runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001554 var Gtp1cUnitdata g_ud;
1555 var integer seq_nr := 23;
Harald Welte57b9b7f2018-02-18 22:28:13 +01001556
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001557 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001558 if (error_ind) {
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001559 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_c));
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001560 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1561 } else {
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001562 var Gtp1cPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001563 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1564 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001565
1566 timer T := 5.0;
1567 T.start;
1568
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001569 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001570 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1571 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001572 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001573 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1574 repeat;
1575 }
1576 [] T.timeout {
1577 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1578 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001579 }
1580}
1581
Harald Welte6f203162018-02-18 22:04:55 +01001582
Harald Welteeded9ad2018-02-17 20:57:34 +01001583/* Table 10.5.156/3GPP TS 24.008 */
1584template (value) QoSV t_QosDefault := {
1585 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1586 delayClass := '100'B, /* best effort */
1587 spare1 := '00'B,
1588 precedenceClass := '010'B, /* normal */
1589 spare2 := '0'B,
1590 peakThroughput := '0000'B, /* subscribed */
1591 meanThroughput := '00000'B, /* subscribed */
1592 spare3 := '000'B,
1593 deliverErroneusSDU := omit,
1594 deliveryOrder := omit,
1595 trafficClass := omit,
1596 maxSDUSize := omit,
1597 maxBitrateUplink := omit,
1598 maxBitrateDownlink := omit,
1599 sduErrorRatio := omit,
1600 residualBER := omit,
1601 trafficHandlingPriority := omit,
1602 transferDelay := omit,
1603 guaranteedBitRateUplink := omit,
1604 guaranteedBitRateDownlink := omit,
1605 sourceStatisticsDescriptor := omit,
1606 signallingIndication := omit,
1607 spare4 := omit,
1608 maxBitrateDownlinkExt := omit,
1609 guaranteedBitRateDownlinkExt := omit,
1610 maxBitrateUplinkExt := omit,
1611 guaranteedBitRateUplinkExt := omit,
1612 maxBitrateDownlinkExt2 := omit,
1613 guaranteedBitRateDownlinkExt2 := omit,
1614 maxBitrateUplinkExt2 := omit,
1615 guaranteedBitRateUplinkExt2 := omit
1616}
1617
1618/* 10.5.6.4 / 3GPP TS 24.008 */
1619template (value) PDPAddressV t_AddrIPv4dyn := {
1620 pdpTypeOrg := '0001'B, /* IETF */
1621 spare := '0000'B,
1622 pdpTypeNum := '21'O, /* IPv4 */
1623 addressInfo := omit
1624}
1625template (value) PDPAddressV t_AddrIPv6dyn := {
1626 pdpTypeOrg := '0001'B, /* IETF */
1627 spare := '0000'B,
1628 pdpTypeNum := '53'O, /* IPv6 */
1629 addressInfo := omit
1630}
1631
Harald Welte37692d82018-02-18 15:21:34 +01001632template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001633 tid := '000'B,
1634 nsapi := '0101'B, /* < 5 are reserved */
1635 sapi := '0011'B, /* 3/5/9/11 */
1636 qos := t_QosDefault,
1637 addr := t_AddrIPv4dyn,
1638 apn := omit,
1639 pco := omit,
1640 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001641 gtp_resp_cause := int2oct(128, 1),
1642 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001643
1644 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001645 ggsn_tei_c := f_rnd_octstring(4),
1646 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001647 ggsn_ip_c := f_inet_addr(ggsn_ip),
1648 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001649 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001650
Harald Welteeded9ad2018-02-17 20:57:34 +01001651 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001652 sgsn_tei_u := omit,
1653 sgsn_ip_c := omit,
1654 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001655}
1656
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001657template (value) Gtp1uPeer ts_GtpPeerU(octetstring ip) := {
Harald Welte37692d82018-02-18 15:21:34 +01001658 connId := 1,
1659 remName := f_inet_ntoa(ip),
1660 remPort := GTP1U_PORT
1661}
1662
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001663template (value) Gtp1cPeer ts_GtpPeerC(octetstring ip) := {
Harald Welte37692d82018-02-18 15:21:34 +01001664 connId := 1,
1665 remName := f_inet_ntoa(ip),
1666 remPort := GTP1C_PORT
1667}
1668
1669private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001670 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
Harald Welte37692d82018-02-18 15:21:34 +01001671 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1672}
1673
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001674private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1675 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001676 repeat;
1677 }
1678}
1679
1680template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1681 pDU_SN_UNITDATA := {
1682 nsapi := nsapi,
1683 moreBit := ?,
1684 snPduType := '1'B,
1685 firstSegmentIndicator := ?,
1686 spareBit := ?,
1687 pcomp := ?,
1688 dcomp := ?,
1689 npduNumber := ?,
1690 segmentNumber := ?,
1691 npduNumberContinued := ?,
1692 dataSegmentSnUnitdataPdu := payload
1693 }
1694}
1695
1696/* simple case: single segment, no compression */
1697template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1698 pDU_SN_UNITDATA := {
1699 nsapi := nsapi,
1700 moreBit := '0'B,
1701 snPduType := '1'B,
1702 firstSegmentIndicator := '1'B,
1703 spareBit := '0'B,
1704 pcomp := '0000'B,
1705 dcomp := '0000'B,
1706 npduNumber := '0000'B,
1707 segmentNumber := '0000'B,
1708 npduNumberContinued := '00'O,
1709 dataSegmentSnUnitdataPdu := payload
1710 }
1711}
1712
1713/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001714private 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 +02001715runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001716 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001717 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1718 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001719 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001720 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1721 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001722 [] as_xid(apars, ran_index);
1723 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001724 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1725 [expect_fwd] T.timeout {
1726 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1727 mtc.stop;
1728 }
1729 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1730 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1731 mtc.stop;
1732 }
1733 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001734 }
1735}
1736
Harald Welte64d6b512020-06-17 16:42:00 +02001737/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001738private 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 +02001739runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001740 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01001741 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
Harald Welte37692d82018-02-18 15:21:34 +01001742 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001743 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, n_u));
Harald Welte37692d82018-02-18 15:21:34 +01001744 /* Expect PDU via GTP from SGSN on simulated GGSN */
1745 alt {
1746 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1747 }
1748}
1749
Harald Welteeded9ad2018-02-17 20:57:34 +01001750private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001751 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001752
1753 /* first perform regular attach */
1754 f_TC_attach(id);
1755
1756 f_pdp_ctx_act(apars);
1757}
1758testcase TC_attach_pdp_act() runs on test_CT {
1759 var BSSGP_ConnHdlr vc_conn;
1760 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001761 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001762 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001763 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001764}
Harald Welteb2124b22018-02-16 22:26:56 +01001765
Harald Welte835b15f2018-02-18 14:39:11 +01001766/* PDP Context activation for not-attached subscriber; expect fail */
1767private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001768 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001769 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 +01001770 apars.apn, apars.pco));
1771 alt {
1772 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001773 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001774 setverdict(pass);
1775 }
1776 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1777 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001778 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001779 }
Harald Welte955aa942019-05-03 01:29:29 +02001780 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001781 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001782 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001783 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001784 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001785 }
1786}
1787testcase TC_pdp_act_unattached() runs on test_CT {
1788 var BSSGP_ConnHdlr vc_conn;
1789 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001790 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001791 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001792 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001793}
1794
Harald Welte37692d82018-02-18 15:21:34 +01001795/* ATTACH + PDP CTX ACT + user plane traffic */
1796private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1797 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1798
1799 /* first perform regular attach */
1800 f_TC_attach(id);
1801 /* then activate PDP context */
1802 f_pdp_ctx_act(apars);
1803 /* then transceive a downlink PDU */
1804 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1805 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1806}
1807testcase TC_attach_pdp_act_user() runs on test_CT {
1808 var BSSGP_ConnHdlr vc_conn;
1809 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001810 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001811 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001812 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001813}
1814
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001815/* ATTACH + PDP CTX ACT; reject from GGSN */
1816private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1817 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1818
1819 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1820 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1821
1822 /* first perform regular attach */
1823 f_TC_attach(id);
1824 /* then activate PDP context */
1825 f_pdp_ctx_act(apars);
1826}
1827testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1828 var BSSGP_ConnHdlr vc_conn;
1829 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001830 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001831 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001832 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001833}
Harald Welte835b15f2018-02-18 14:39:11 +01001834
Harald Welte6f203162018-02-18 22:04:55 +01001835/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1836private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1837 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1838
1839 /* first perform regular attach */
1840 f_TC_attach(id);
1841 /* then activate PDP context */
1842 f_pdp_ctx_act(apars);
1843 /* then transceive a downlink PDU */
1844 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1845 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1846
1847 f_pdp_ctx_deact_mo(apars, '00'O);
1848}
1849testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1850 var BSSGP_ConnHdlr vc_conn;
1851 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001852 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 +01001853 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001854 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001855}
1856
Harald Welte57b9b7f2018-02-18 22:28:13 +01001857/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1858private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1859 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1860
1861 /* first perform regular attach */
1862 f_TC_attach(id);
1863 /* then activate PDP context */
1864 f_pdp_ctx_act(apars);
1865 /* then transceive a downlink PDU */
1866 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1867 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1868
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001869 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001870}
1871testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1872 var BSSGP_ConnHdlr vc_conn;
1873 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001874 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 +01001875 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001876 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001877}
1878
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001879/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1880private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1881 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1882 var Gtp1cUnitdata g_ud;
1883 var integer i;
1884 var OCT1 cause_regular_deact := '24'O;
1885
1886 /* first perform regular attach + PDP context act */
1887 f_TC_attach(id);
1888 f_pdp_ctx_act(apars);
1889
1890 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1891 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1892
1893 for (i := 0; i < 2; i := i+1) {
1894 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1895 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1896 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1897 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1898 }
1899 }
1900
1901 alt {
1902 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1903 setverdict(pass);
1904 }
1905 [] as_xid(apars, 0);
1906 }
1907
1908 /* Make sure second DeactPdpAccept is sent: */
1909 timer T := 2.0;
1910 T.start;
1911 alt {
1912 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1913 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1914 }
1915 [] T.timeout {
1916 setverdict(pass);
1917 }
1918 }
1919
1920 setverdict(pass);
1921}
1922testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1923 var BSSGP_ConnHdlr vc_conn;
1924 f_init();
1925 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1926 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001927 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001928}
1929
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001930/* ATTACH + ATTACH (2nd) */
1931private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1932 g_pars.t_guard := 5.0;
1933
1934 /* first perform regular attach */
1935 f_TC_attach(id);
1936
1937 /* second to perform regular attach */
1938 f_TC_attach(id);
1939}
1940
1941
1942testcase TC_attach_second_attempt() runs on test_CT {
1943 var BSSGP_ConnHdlr vc_conn;
1944 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001945 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001946 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001947 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001948}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001949
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001950private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1951 var Gtp1cUnitdata g_ud;
1952 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1953 var integer seq_nr;
1954
1955 /* first perform regular attach */
1956 f_TC_attach(id);
1957 /* then activate PDP context */
1958 f_pdp_ctx_act(apars);
1959
1960 /* Wait to receive first echo request and send initial Restart counter */
1961 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1962 BSSGP[0].clear;
1963 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1964 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1965 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1966 }
1967
1968 /* At some point next echo request not answered will timeout and SGSN
1969 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1970 timer T := 3.0 * 6.0 + 16.0;
1971 T.start;
1972 alt {
1973 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1974 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1975 setverdict(pass);
1976 }
1977 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1978 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1979 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1980 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1981 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1982 repeat;
1983 }
1984 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1985 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1986 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1987 repeat;
1988 }
1989 [] T.timeout {
1990 setverdict(fail, "BSSGP DeactPdpReq not received");
1991 mtc.stop;
1992 }
1993 [] as_xid(apars);
1994 }
1995 T.stop
1996
1997 setverdict(pass);
1998}
1999/* ATTACH + trigger Recovery procedure through CreatePdpResp */
2000testcase TC_attach_echo_timeout() runs on test_CT {
2001 var BSSGP_ConnHdlr vc_conn;
2002 g_use_echo := true;
2003 f_init();
2004 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
2005 vc_conn.done;
2006 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002007 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002008}
2009
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002010private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002011 var Gtp1cUnitdata g_ud;
2012 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2013
2014 /* first perform regular attach */
2015 f_TC_attach(id);
2016 /* Activate a pdp context against the GGSN */
2017 f_pdp_ctx_act(apars);
2018 /* Wait to receive first echo request and send initial Restart counter */
2019 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
2020 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
2021 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
2022 }
2023 /* Wait to receive second echo request and send incremented Restart
2024 counter. This will fake a restarted GGSN, and pdp ctx allocated
2025 should be released by SGSN */
2026 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
2027 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
2028 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
2029 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
2030 }
2031 var OCT1 cause_network_failure := int2oct(38, 1)
2032 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002033 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002034 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002035 setverdict(pass);
2036 }
2037 [] as_xid(apars);
2038 }
2039 setverdict(pass);
2040}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002041/* ATTACH + trigger Recovery procedure through EchoResp */
2042testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002043 var BSSGP_ConnHdlr vc_conn;
2044 g_use_echo := true
2045 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002046 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 +02002047 vc_conn.done;
2048 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002049 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02002050}
2051
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002052private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
2053 var Gtp1cUnitdata g_ud;
2054 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2055 var integer seq_nr := 23;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002056 /* first perform regular attach */
2057 f_TC_attach(id);
2058
2059 /* Use this CTX ACT to send initial Restart counter to SGSN. */
2060 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
2061 apars.exp_rej_cause := '1a'O; /* insufficient resources */
2062 f_pdp_ctx_act(apars, true);
2063
2064 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
2065/* received. */
2066 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
2067
2068 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
2069 would be great to have an active pdp context here before triggering
2070 Recovery, and making sure the the DEACT request is sent by the SGSN.
2071 */
2072
2073 /* Activate a pdp context against the GGSN, send incremented Recovery
2074 IE. This should trigger the recovery path, but still this specific
2075 CTX activation should work. */
2076 apars.exp_rej_cause := omit; /* default value for tests */
2077 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
2078 f_pdp_ctx_act(apars, true);
2079
2080 setverdict(pass);
2081}
2082/* ATTACH + trigger Recovery procedure through CreatePdpResp */
2083testcase TC_attach_restart_ctr_create() runs on test_CT {
2084 var BSSGP_ConnHdlr vc_conn;
2085 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002086 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 +02002087 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002088 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002089}
2090
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002091/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
2092private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
2093 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2094 var integer seq_nr := 23;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01002095 var Gtp1cPeer peer;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002096 var integer i;
2097
2098 /* first perform regular attach */
2099 f_TC_attach(id);
2100 /* then activate PDP context */
2101 f_pdp_ctx_act(apars);
2102
Alexander Couzens0e510e62018-07-28 23:06:00 +02002103 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002104 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2105 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
2106
2107 for (i := 0; i < 5; i := i+1) {
2108 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002109 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002110 [] as_xid(apars);
2111 }
2112 }
2113
2114 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
2115
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002116 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002117 setverdict(pass);
2118}
2119testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
2120 var BSSGP_ConnHdlr vc_conn;
2121 f_init();
2122 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002123 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 +02002124 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002125 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002126}
2127
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002128/* ATTACH + PDP CTX ACT dropped + retrans */
2129private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2130 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2131 var Gtp1cUnitdata g_ud_first, g_ud_second;
2132 /* first perform regular attach */
2133 f_TC_attach(id);
2134
2135 /* then activate PDP context on the Gb side */
2136 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2137 apars.apn, apars.pco), 0);
2138
2139 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2140 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2141 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2142 if (g_ud_first != g_ud_second) {
2143 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2144 mtc.stop;
2145 }
2146 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2147 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2148 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2149 apars.sgsn_tei_c, apars.gtp_resp_cause,
2150 apars.ggsn_tei_c, apars.ggsn_tei_u,
2151 apars.nsapi,
2152 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2153 omit, omit));
2154 }
Harald Welte955aa942019-05-03 01:29:29 +02002155 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002156
2157 /* Now the same with Deact */
2158 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2159 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2160 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2161 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2162 if (g_ud_first != g_ud_second) {
2163 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2164 mtc.stop;
2165 }
2166 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2167 BSSGP[0].clear;
2168 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2169 }
2170 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002171 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002172 setverdict(pass);
2173 }
2174 [] as_xid(apars, 0);
2175 }
2176
2177 setverdict(pass);
2178}
2179testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2180 var BSSGP_ConnHdlr vc_conn;
2181 f_init();
2182 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2183 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002184 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002185}
2186
2187/* Test that SGSN GTP response retransmit queue works fine */
2188private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2189 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2190 var integer seq_nr := 23;
2191 var Gtp1cUnitdata g_ud_first, g_ud_second;
2192 var template Gtp1cUnitdata g_delete_req;
2193 /* first perform regular attach + PDP context act */
2194 f_TC_attach(id);
2195 f_pdp_ctx_act(apars);
2196
2197 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2198 BSSGP[0].clear;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01002199 var Gtp1cPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002200 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2201 GTP.send(g_delete_req);
2202 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002203 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002204 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2205 }
2206 [] as_xid(apars, 0);
2207 }
2208 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2209 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2210 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2211 mtc.stop;
2212 }
2213 };
2214
2215 /* Send duplicate DeleteCtxReq */
2216 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2217 GTP.send(g_delete_req);
2218 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2219 if (g_ud_first != g_ud_second) {
2220 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2221 mtc.stop;
2222 }
2223 }
2224
2225 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2226 * is handled differently by SGSN (expect "non-existent" cause) */
2227 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2228 GTP.send(g_delete_req);
2229 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2230 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2231 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2232 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2233 mtc.stop;
2234 }
2235 }
2236
2237 setverdict(pass);
2238}
2239testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2240 var BSSGP_ConnHdlr vc_conn;
2241 f_init();
2242 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2243 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002244 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002245}
2246
Alexander Couzens5e307b42018-05-22 18:12:20 +02002247private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2248 /* MS: perform regular attach */
2249 f_TC_attach(id);
2250
2251 /* HLR: cancel the location request */
2252 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2253 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002254
2255 /* ensure no Detach Request got received */
2256 timer T := 5.0;
2257 T.start;
2258 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002259 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002260 T.stop;
2261 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002262 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002263 }
2264 [] T.timeout {
2265 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002266 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002267 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002268 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002269 repeat;
2270 }
2271 }
2272}
2273
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002274/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2275private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2276 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2277
2278 /* first perform regular attach */
2279 f_TC_attach(id);
2280 /* then activate PDP context */
2281 f_pdp_ctx_act(apars);
2282 /* then transceive a downlink PDU */
2283 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2284
2285 /* Send Error indication as response from upload PDU and expect deact towards MS */
2286 f_pdp_ctx_deact_mt(apars, true);
2287}
2288testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2289 var BSSGP_ConnHdlr vc_conn;
2290 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002291 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 +02002292 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002293 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002294}
2295
Alexander Couzens5e307b42018-05-22 18:12:20 +02002296testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2297 /* MS <-> SGSN: GMM Attach
2298 * HLR -> SGSN: Cancel Location Request
2299 * HLR <- SGSN: Cancel Location Ack
2300 */
2301 var BSSGP_ConnHdlr vc_conn;
2302 f_init();
2303 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002304 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002305 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002306 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002307}
2308
2309
Alexander Couzensc87967a2018-05-22 16:09:54 +02002310private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2311 /* MS: perform regular attach */
2312 f_TC_attach(id);
2313
2314 /* HLR: cancel the location request */
2315 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2316 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2317 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2318
2319 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002320 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002321 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002322
2323 setverdict(pass);
2324}
2325
2326testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2327 /* MS <-> SGSN: GMM Attach
2328 * HLR -> SGSN: Cancel Location Request
2329 * HLR <- SGSN: Cancel Location Ack
2330 * MS <- SGSN: Detach Request
2331 * SGSN-> MS: Detach Complete
2332 */
2333 var BSSGP_ConnHdlr vc_conn;
2334 f_init();
2335 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002336 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002337 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002338 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002339}
2340
2341
Alexander Couzens6c47f292018-05-22 17:09:49 +02002342private function f_hlr_location_cancel_request_unknown_subscriber(
2343 charstring id,
2344 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2345
2346 /* HLR: cancel the location request */
2347 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2348
2349 /* cause 2 = IMSI_UNKNOWN */
2350 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2351
2352 setverdict(pass);
2353}
2354
2355private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002356 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002357}
2358
2359testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2360 /* HLR -> SGSN: Cancel Location Request
2361 * HLR <- SGSN: Cancel Location Error
2362 */
2363
2364 var BSSGP_ConnHdlr vc_conn;
2365 f_init();
2366 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002367 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 +02002368 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002369 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002370}
2371
2372private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002373 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002374}
2375
2376testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2377 /* HLR -> SGSN: Cancel Location Request
2378 * HLR <- SGSN: Cancel Location Error
2379 */
2380
2381 var BSSGP_ConnHdlr vc_conn;
2382 f_init();
2383 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002384 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 +02002385 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002386 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002387}
2388
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002389private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2390 f_TC_attach(id);
2391 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2392}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002393
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002394testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2395 /* MS <-> SGSN: Attach
2396 * MS -> SGSN: Detach Req (Power off)
2397 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2398 */
2399 var BSSGP_ConnHdlr vc_conn;
2400 var integer id := 33;
2401 var charstring imsi := hex2str(f_gen_imsi(id));
2402
2403 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002404 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002405 vc_conn.done;
2406
2407 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002408 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002409}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002410
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002411/* Attempt an attach, but loose the Identification Request (IMEI) */
2412private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2413 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002414 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002415
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002416 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 +02002417
2418 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002419 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002420 /* break */
2421 }
Harald Welte955aa942019-05-03 01:29:29 +02002422 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002423 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002424 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002425 repeat;
2426 }
Harald Welte955aa942019-05-03 01:29:29 +02002427 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002428 /* ignore ID REQ IMEI */
2429 count_req := count_req + 1;
2430 repeat;
2431 }
2432 }
2433 if (count_req != 5) {
2434 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002435 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002436 }
2437 setverdict(pass);
2438}
2439
2440testcase TC_attach_no_imei_response() runs on test_CT {
2441 /* MS -> SGSN: Attach Request IMSI
2442 * MS <- SGSN: Identity Request IMSI (optional)
2443 * MS -> SGSN: Identity Response IMSI (optional)
2444 * MS <- SGSN: Identity Request IMEI
2445 * MS -x SGSN: no response
2446 * MS <- SGSN: re-send: Identity Request IMEI 4x
2447 * MS <- SGSN: Attach Reject
2448 */
2449 var BSSGP_ConnHdlr vc_conn;
2450 f_init();
2451 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002452 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 +02002453 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002454 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002455}
2456
Alexander Couzens53f20562018-06-12 16:24:12 +02002457/* Attempt an attach, but loose the Identification Request (IMSI) */
2458private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2459 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002460 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002461
2462 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2463 g_pars.p_tmsi := 'c0000035'O;
2464
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002465 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 +02002466
2467 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002468 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002469 /* break */
2470 }
Harald Welte955aa942019-05-03 01:29:29 +02002471 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002472 /* ignore ID REQ IMSI */
2473 count_req := count_req + 1;
2474 repeat;
2475 }
Harald Welte955aa942019-05-03 01:29:29 +02002476 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002477 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002478 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002479 repeat;
2480 }
2481 }
2482 if (count_req != 5) {
2483 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002484 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002485 }
2486 setverdict(pass);
2487}
2488
2489testcase TC_attach_no_imsi_response() runs on test_CT {
2490 /* MS -> SGSN: Attach Request TMSI (unknown)
2491 * MS <- SGSN: Identity Request IMEI (optional)
2492 * MS -> SGSN: Identity Response IMEI (optional)
2493 * MS <- SGSN: Identity Request IMSI
2494 * MS -x SGSN: no response
2495 * MS <- SGSN: re-send: Identity Request IMSI 4x
2496 * MS <- SGSN: Attach Reject
2497 */
2498 var BSSGP_ConnHdlr vc_conn;
2499 f_init();
2500 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002501 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 +02002502 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002503 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002504}
2505
Alexander Couzenscf818962018-06-05 18:00:00 +02002506private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2507 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2508}
2509
2510testcase TC_attach_check_subscriber_list() runs on test_CT {
2511 /* MS <-> SGSN: Attach
2512 * VTY -> SGSN: Check if MS is in subscriber cache
2513 */
2514 var BSSGP_ConnHdlr vc_conn;
2515 var integer id := 34;
2516 var charstring imsi := hex2str(f_gen_imsi(id));
2517
2518 f_init();
2519 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002520 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002521 vc_conn.done;
2522
2523 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2524 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002525 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002526}
2527
Alexander Couzensf9858652018-06-07 16:14:53 +02002528private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2529 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002530 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002531
2532 /* unregister the old IMSI */
2533 f_bssgp_client_unregister(g_pars.imsi);
2534 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002535 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002536 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002537
2538 /* there is no auth */
2539 g_pars.net.expect_auth := false;
2540
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002541 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002542 f_gmm_auth();
2543 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002544 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002545 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002546 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002547 }
Harald Welte955aa942019-05-03 01:29:29 +02002548 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2549 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002550 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002551 setverdict(pass);
2552 }
2553 }
2554}
Alexander Couzens03d12242018-08-07 16:13:52 +02002555
2556private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2557
2558 f_TC_attach_closed_foreign(id);
2559 f_TC_attach_closed_imsi_added(id);
2560
2561}
2562
2563
Alexander Couzensf9858652018-06-07 16:14:53 +02002564testcase TC_attach_closed_add_vty() runs on test_CT {
2565 /* VTY-> SGSN: policy close
2566 * MS -> SGSN: Attach Request
2567 * MS <- SGSN: Identity Request IMSI
2568 * MS -> SGSN: Identity Response IMSI
2569 * MS <- SGSN: Attach Reject
2570 * VTY-> SGSN: policy imsi-acl add IMSI
2571 * MS -> SGSN: Attach Request
2572 * MS <- SGSN: Identity Request IMSI
2573 * MS -> SGSN: Identity Response IMSI
2574 * MS <- SGSN: Identity Request IMEI
2575 * MS -> SGSN: Identity Response IMEI
2576 * MS <- SGSN: Attach Accept
2577 */
2578 var BSSGP_ConnHdlr vc_conn;
2579 f_init();
2580 f_sleep(1.0);
2581 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2582 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002583 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2584 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002585 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002586 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002587 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002588 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002589}
2590
Alexander Couzens0085bd72018-06-12 19:08:44 +02002591/* Attempt an attach, but never answer a Attach Complete */
2592private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2593 var integer count_req := 0;
2594
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002595 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 +02002596 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002597 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07002598 as_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002599
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002600 timer T := 10.0;
2601 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002602 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002603 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002604 /* break */
2605 }
Harald Welte955aa942019-05-03 01:29:29 +02002606 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002607 /* ignore */
2608 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002609 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002610 repeat;
2611 }
2612 }
2613 if (count_req != 5) {
2614 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002615 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002616 }
2617 setverdict(pass);
2618}
2619
2620testcase TC_attach_check_complete_resend() runs on test_CT {
2621 /* MS -> SGSN: Attach Request IMSI
2622 * MS <- SGSN: Identity Request *
2623 * MS -> SGSN: Identity Response *
2624 * MS <- SGSN: Attach Complete 5x
2625 */
2626 var BSSGP_ConnHdlr vc_conn;
2627 f_init();
2628 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002629 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 +02002630 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002631 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002632}
2633
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002634friend altstep as_routing_area_update_gb(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002635 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002636
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002637 [] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002638 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2639 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002640 setverdict(pass);
2641 }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002642 [] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
2643 setverdict(fail, "Unexpected RAU Reject");
2644 mtc.stop;
2645 }
2646}
2647friend altstep as_routing_area_update_iu(integer ran_index := 0) runs on BSSGP_ConnHdlr {
2648 var PDU_DTAP_PS_MT mt;
2649
2650 [] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002651 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2652 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002653 setverdict(pass);
2654 }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002655 [] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002656 setverdict(fail, "Unexpected RAU Reject");
2657 mtc.stop;
2658 }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002659 [] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?,
2660 uia_key := oct2bit(g_pars.vec.ik),
2661 key_sts := ?)) {
2662 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2663 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
2664 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
2665 repeat;
2666 }
2667}
2668friend altstep as_routing_area_update(integer ran_index := 0) runs on BSSGP_ConnHdlr {
2669 [is_gb(ran_index)] as_routing_area_update_gb(ran_index);
2670 [is_iu(ran_index)] as_routing_area_update_iu(ran_index);
2671}
Alexander Couzens5d56f522019-09-03 12:36:18 +02002672
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002673friend function f_routing_area_update(RoutingAreaIdentificationV old_ra,
2674 GprsUpdateType upd_type := GPRS_UPD_T_RA,
2675 integer ran_index := 0,
2676 float Tval := 2.0) runs on BSSGP_ConnHdlr {
2677 var template (omit) OCT4 p_tmsi := omit;
2678 timer T := Tval;
2679
2680 if (is_iu(ran_index)) {
2681 p_tmsi := g_pars.p_tmsi;
2682 }
2683
2684 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), upd_type, old_ra, p_tmsi := p_tmsi), ran_index);
2685
2686 T.start;
2687 alt {
2688 [] as_routing_area_update(ran_index) { setverdict(pass); }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002689 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2690 [is_iu(ran_index)] BSSAP.receive { repeat; }
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002691 [] T.timeout {
2692 setverdict(fail, "Timeout completing the RAU procedure");
2693 mtc.stop;
2694 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002695 }
2696}
2697
Alexander Couzensbfda9212018-07-31 03:17:33 +02002698private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002699 /* first perform regular attach */
2700 f_TC_attach(id);
2701
2702 /* then send RAU */
2703 f_routing_area_update(g_pars.ra);
2704
2705 /* do another RAU */
2706 f_routing_area_update(g_pars.ra);
2707
2708 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2709}
2710
2711testcase TC_attach_rau_a_a() runs on test_CT {
2712 /* MS <-> SGSN: Successful Attach
2713 * MS -> SGSN: Routing Area Update Request
2714 * MS <- SGSN: Routing Area Update Accept
2715 * MS -> SGSN: Routing Area Update Request
2716 * MS <- SGSN: Routing Area Update Accept
2717 * MS -> SGSN: Detach (PowerOff)
2718 */
2719 var BSSGP_ConnHdlr vc_conn;
2720 f_init();
2721 f_sleep(1.0);
2722 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2723 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002724 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002725}
2726
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002727private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002728 f_TC_attach(id);
2729
2730 log("attach complete sending rau");
Vadim Yanitskiy3d815762024-04-06 05:37:35 +07002731 f_routing_area_update(g_pars.ra);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002732
2733 log("rau complete unregistering");
2734 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002735 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002736
2737 log("sending second RAU via different RA");
Vadim Yanitskiyaaf7ce42024-04-21 20:46:51 +07002738 f_routing_area_update(old_ra := g_pars.ra, ran_index := 1);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002739
2740 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2741}
2742
2743testcase TC_attach_rau_a_b() runs on test_CT {
2744 /* MS <-> SGSN: Successful Attach
2745 * MS -> SGSN: Routing Area _a_ Update Request
2746 * MS <- SGSN: Routing Area _a_ Update Accept
2747 * MS -> SGSN: Routing Area _b_ Update Request
2748 * MS <- SGSN: Routing Area _b_ Update Accept
2749 * MS -> SGSN: Detach (PowerOff)
2750 */
2751 var BSSGP_ConnHdlr vc_conn;
2752 f_init();
2753 f_sleep(1.0);
2754 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2755 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002756 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002757}
2758
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002759private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2760 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002761 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002762 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002763 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002764
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002765 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002766
2767 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002768 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002769 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2770 mtc.stop;
2771 }
Harald Welte955aa942019-05-03 01:29:29 +02002772 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002773 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002774 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002775 repeat;
2776 }
Harald Welte955aa942019-05-03 01:29:29 +02002777 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002778 /* send out a second GMM_Attach Request.
2779 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2780 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002781 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002782 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002783 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002784 }
2785 }
2786 f_sleep(1.0);
2787
2788 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2789 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002790 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002791 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002792 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002793 repeat;
2794 }
Harald Welte955aa942019-05-03 01:29:29 +02002795 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002796 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2797 mtc.stop;
2798 }
Harald Welte955aa942019-05-03 01:29:29 +02002799 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002800 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2801 mtc.stop;
2802 }
Harald Welte955aa942019-05-03 01:29:29 +02002803 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2804 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002805 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002806 setverdict(pass);
2807 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2808 }
2809 }
2810}
2811
2812testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2813 /* Testing if the SGSN ignore Attach Request with the exact same content */
2814 /* MS -> SGSN: Attach Request IMSI
2815 * MS <- SGSN: Identity Request IMSI (optional)
2816 * MS -> SGSN: Identity Response IMSI (optional)
2817 * MS <- SGSN: Identity Request IMEI
2818 * MS -> SGSN: Attach Request (2nd)
2819 * MS <- SGSN: Identity Response IMEI
2820 * MS <- SGSN: Attach Accept
2821 * MS -> SGSN: Attach Complete
2822 */
2823 var BSSGP_ConnHdlr vc_conn;
2824 f_init();
2825 f_sleep(1.0);
2826 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2827 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2828 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002829 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002830}
2831
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002832private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002833 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2834
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002835 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 +02002836
2837 /* send Attach Request */
2838 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2839 * 3G auth vectors */
2840 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2841 /* The thing is, if the solSACapability is 'omit', then the
2842 * revisionLevelIndicatior is at the wrong place! */
2843 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002844 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002845
2846 /* do the auth */
2847 var PDU_L3_MS_SGSN l3_mo;
2848 var PDU_L3_SGSN_MS l3_mt;
2849 var default di := activate(as_mm_identity());
2850
2851 var GSUP_IE auth_tuple;
2852 var template AuthenticationParameterAUTNTLV autn;
2853
2854 g_pars.vec := f_gen_auth_vec_3g();
2855 autn := {
2856 elementIdentifier := '28'O,
2857 lengthIndicator := lengthof(g_pars.vec.autn),
2858 autnValue := g_pars.vec.autn
2859 };
2860 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2861 g_pars.vec.sres,
2862 g_pars.vec.kc,
2863 g_pars.vec.ik,
2864 g_pars.vec.ck,
2865 g_pars.vec.autn,
2866 g_pars.vec.res));
2867 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2868 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2869 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2870
2871 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2872 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002873 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002874
2875 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002876 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002877
2878 /* wait for the GSUP resync request */
2879 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2880 g_pars.imsi,
2881 g_pars.vec.auts,
2882 g_pars.vec.rand));
2883
2884 /* generate new key material */
2885 g_pars.vec := f_gen_auth_vec_3g();
2886 autn := {
2887 elementIdentifier := '28'O,
2888 lengthIndicator := lengthof(g_pars.vec.autn),
2889 autnValue := g_pars.vec.autn
2890 };
2891
2892 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2893 g_pars.vec.sres,
2894 g_pars.vec.kc,
2895 g_pars.vec.ik,
2896 g_pars.vec.ck,
2897 g_pars.vec.autn,
2898 g_pars.vec.res));
2899 /* send new key material */
2900 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2901
2902 /* wait for the new Auth Request */
2903 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2904 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002905 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002906 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002907 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 +02002908 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2909 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2910 valueField := substr(g_pars.vec.res, 0, 4)
2911 };
2912 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2913 elementIdentifier := '21'O,
2914 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2915 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2916 };
2917 l3_mo := valueof(auth_ciph_resp);
2918 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2919 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2920 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2921 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2922 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002923 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002924 deactivate(di);
2925
2926 /* Expect SGSN to perform LU with HLR */
Vadim Yanitskiy24d22822023-06-27 19:01:26 +07002927 as_gmm_gsup_lu_isd();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002928
Harald Welte955aa942019-05-03 01:29:29 +02002929 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2930 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002931 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002932 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002933 setverdict(pass);
2934}
2935
2936testcase TC_attach_usim_resync() runs on test_CT {
2937 /* MS -> SGSN: Attach Request
2938 * MS <- SGSN: Identity Request IMSI
2939 * MS -> SGSN: Identity Response IMSI
2940 * MS <- SGSN: Identity Request IMEI
2941 * MS -> SGSN: Identity Response IMEI
2942 * HLR<- SGSN: SAI Request
2943 * HLR-> SGSN: SAI Response
2944 * MS <- SGSN: Auth Request
2945 * MS -> SGSN: Auth Failure (with AUTS)
2946 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2947 * HLR-> SGSN: SAI Response (new key material)
2948 * MS <- SGSN: Auth Request (new key material)
2949 * MS -> SGSN: Auth Response
2950 * MS <- SGSN: Attach Accept
2951 * MS -> SGSN: Attach Complete
2952 */
2953 var BSSGP_ConnHdlr vc_conn;
2954 f_init();
2955 f_sleep(1.0);
2956 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2957 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002958 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002959}
2960
Eric Wildc555be52021-05-15 19:48:22 +02002961private function f_TC_attach_usim_crypt(OCT1 netcap_a2345, BIT3 auth_req_ciph) runs on BSSGP_ConnHdlr {
2962 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2963
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07002964 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 +02002965 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.spare_octets := netcap_a2345; /* GEA2345... */
2966
2967 /* send Attach Request */
2968 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2969 * 3G auth vectors */
2970 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2971 /* The thing is, if the solSACapability is 'omit', then the
2972 * revisionLevelIndicatior is at the wrong place! */
2973 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2974 f_send_l3(attach_req);
2975
2976 /* do the auth */
2977 var PDU_L3_MS_SGSN l3_mo;
2978 var PDU_L3_SGSN_MS l3_mt;
2979 var default di := activate(as_mm_identity());
2980
2981 var GSUP_IE auth_tuple;
2982 var template AuthenticationParameterAUTNTLV autn;
2983
2984 g_pars.vec := f_gen_auth_vec_3g();
2985 autn := {
2986 elementIdentifier := '28'O,
2987 lengthIndicator := lengthof(g_pars.vec.autn),
2988 autnValue := g_pars.vec.autn
2989 };
2990 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2991 g_pars.vec.sres,
2992 g_pars.vec.kc,
2993 g_pars.vec.ik,
2994 g_pars.vec.ck,
2995 g_pars.vec.autn,
2996 g_pars.vec.res));
2997 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2998 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2999 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
3000
3001 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand, auth_req_ciph);
3002 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
3003 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
3004
3005 setverdict(pass);
3006 deactivate(di);
3007}
3008
3009private function f_TC_attach_usim_a54_a54(charstring id) runs on BSSGP_ConnHdlr {
3010 f_TC_attach_usim_crypt('10'O, '100'B);
3011}
3012
3013private function f_TC_attach_usim_a54_a53(charstring id) runs on BSSGP_ConnHdlr {
3014 f_TC_attach_usim_crypt('20'O, '011'B);
3015}
3016
3017private function f_TC_attach_usim_a53_a54(charstring id) runs on BSSGP_ConnHdlr {
3018 f_TC_attach_usim_crypt('30'O, '011'B);
3019}
3020
3021private function f_TC_attach_usim_a50_a54(charstring id) runs on BSSGP_ConnHdlr {
3022 f_TC_attach_usim_crypt('30'O, '000'B);
3023}
3024
3025private function f_TC_attach_usim_a54_a50(charstring id) runs on BSSGP_ConnHdlr {
3026 f_TC_attach_usim_crypt('00'O, '000'B);
3027}
3028
3029testcase TC_attach_usim_a54_a54() runs on test_CT {
3030 var BSSGP_ConnHdlr vc_conn;
3031 f_init();
3032 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003033 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003034 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a54), testcasename(), g_gb, 40);
3035 vc_conn.done;
3036 f_cleanup();
3037}
3038
3039testcase TC_attach_usim_a54_a53() runs on test_CT {
3040 var BSSGP_ConnHdlr vc_conn;
3041 f_init();
3042 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003043 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003044 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a53), testcasename(), g_gb, 40);
3045 vc_conn.done;
3046 f_cleanup();
3047}
3048
3049testcase TC_attach_usim_a53_a54() runs on test_CT {
3050 var BSSGP_ConnHdlr vc_conn;
3051 f_init();
3052 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003053 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3");
Eric Wildc555be52021-05-15 19:48:22 +02003054 vc_conn := f_start_handler(refers(f_TC_attach_usim_a53_a54), testcasename(), g_gb, 40);
3055 vc_conn.done;
3056 f_cleanup();
3057}
3058
3059testcase TC_attach_usim_a50_a54() runs on test_CT {
3060 var BSSGP_ConnHdlr vc_conn;
3061 f_init();
3062 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003063 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0");
Eric Wildc555be52021-05-15 19:48:22 +02003064 vc_conn := f_start_handler(refers(f_TC_attach_usim_a50_a54), testcasename(), g_gb, 40);
3065 vc_conn.done;
3066 f_cleanup();
3067}
3068
3069testcase TC_attach_usim_a54_a50() runs on test_CT {
3070 var BSSGP_ConnHdlr vc_conn;
3071 f_init();
3072 f_sleep(1.0);
Vadim Yanitskiy60fcc632021-07-04 01:02:29 +02003073 f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4");
Eric Wildc555be52021-05-15 19:48:22 +02003074 vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a50), testcasename(), g_gb, 40);
3075 vc_conn.done;
3076 f_cleanup();
3077}
Harald Weltea05b8072019-04-23 22:35:05 +02003078
3079/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
3080private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
3081 f_gmm_attach(false, false);
3082 f_sleep(1.0);
3083 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
3084 /* try to detach to check if SGSN is still alive */
3085 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
3086}
3087testcase TC_llc_null() runs on test_CT {
3088 var BSSGP_ConnHdlr vc_conn;
3089 f_init();
3090 f_sleep(1.0);
3091 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
3092 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003093 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02003094}
3095
Harald Welte645a1512019-04-23 23:18:23 +02003096/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3097private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
3098 f_gmm_attach(false, false);
3099 f_sleep(1.0);
3100 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003101 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003102 setverdict(pass);
3103}
3104testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
3105 var BSSGP_ConnHdlr vc_conn;
3106 f_init();
3107 f_sleep(1.0);
3108 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
3109 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003110 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003111}
3112
3113/* Send LLC SABM to see if the SGSN rejects it properly with DM */
3114private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
3115 f_gmm_attach(false, false);
3116 f_sleep(1.0);
3117 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02003118 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02003119 setverdict(pass);
3120}
3121testcase TC_llc_sabm_dm_ll5() runs on test_CT {
3122 var BSSGP_ConnHdlr vc_conn;
3123 f_init();
3124 f_sleep(1.0);
3125 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
3126 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003127 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02003128}
3129
Harald Welte2aaac1b2019-05-02 10:02:53 +02003130/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
3131private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
3132 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3133 var template (value) XID_Information xid;
3134 var template XID_Information xid_rx;
3135
3136 /* first perform regular attach */
3137 f_TC_attach(id);
3138 /* then activate PDP context */
3139 f_pdp_ctx_act(apars);
3140
3141 /* start MO XID */
3142 xid := { ts_XID_L3(''O) };
3143 xid_rx := { tr_XID_L3(''O) };
3144 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3145 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003146 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003147 [] as_xid(apars);
3148 }
3149 setverdict(pass);
3150}
3151testcase TC_xid_empty_l3() runs on test_CT {
3152 var BSSGP_ConnHdlr vc_conn;
3153 f_init();
3154 f_sleep(1.0);
3155 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
3156 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003157 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003158}
3159
3160private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
3161 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3162 var template (value) XID_Information xid;
3163 var template XID_Information xid_rx;
3164
3165 /* first perform regular attach */
3166 f_TC_attach(id);
3167 /* then activate PDP context */
3168 f_pdp_ctx_act(apars);
3169
3170 /* start MO XID */
3171 xid := { ts_XID_N201U(1234) };
3172 xid_rx := { tr_XID_N201U(1234) };
3173 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
3174 alt {
Harald Welte955aa942019-05-03 01:29:29 +02003175 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02003176 [] as_xid(apars);
3177 }
3178 setverdict(pass);
3179}
3180testcase TC_xid_n201u() runs on test_CT {
3181 var BSSGP_ConnHdlr vc_conn;
3182 f_init();
3183 f_sleep(1.0);
3184 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
3185 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003186 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02003187}
3188
Alexander Couzens6bee0872019-05-11 01:48:50 +02003189private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
3190 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3191
3192 /* first perform regular attach */
3193 f_TC_attach(id);
3194 /* then activate PDP context */
3195 f_pdp_ctx_act(apars);
3196 /* do a normal detach */
3197 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
3198}
3199
3200testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
3201 /* MS -> SGSN: Attach Request
3202 * MS <-> SGSN: [..]
3203 * MS -> SGSN: Attach Complete
3204 * MS -> SGSN: PDP Activate Request
3205 * MS <- SGSN: PDP Activate Accept
3206 * MS -> SGSN: GMM Detach Request
3207 * MS <- SGSN: GMM Detach Accept
3208 */
3209 var BSSGP_ConnHdlr vc_conn;
3210 f_init();
3211 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
3212 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02003213 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02003214}
Harald Welte645a1512019-04-23 23:18:23 +02003215
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003216private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
3217 var RoutingAreaIdentificationV old_ra := f_random_RAI();
3218 var RoutingAreaIdentificationV new_ra := f_random_RAI();
3219 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003220 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 +01003221 var PDU_L3_SGSN_MS l3_mt;
3222
3223 f_send_l3(attach_req, 0);
3224
3225 BSSGP[0].receive(tr_GMM_ID_REQ(?));
3226
3227 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
3228 alt {
3229 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
3230 setverdict(pass);
3231 }
3232 [] BSSGP[0].receive { repeat; }
3233 }
3234}
3235
3236/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
3237 * See OS#3957 and OS#4245 for more information.
3238 */
3239testcase TC_attach_req_id_req_ra_update() runs on test_CT {
3240 /*
3241 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
3242 * MS <-- SGSN: Identity Request (IMEI)
3243 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
3244 */
3245 var BSSGP_ConnHdlr vc_conn;
3246 f_init();
3247 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
3248 vc_conn.done;
3249 f_cleanup();
3250}
3251
Harald Welte8e5932e2020-06-17 22:12:54 +02003252private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
3253var PDU_BSSGP rx;
3254[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
3255 setverdict(fail, "Received unexpected PS PAGING: ", rx);
3256 mtc.stop;
3257 }
3258}
3259
3260/* SUSPEND, then DL traffic: should not pass + no paging expected */
3261private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3262 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3263 var default d;
3264
3265 /* first perform regular attach */
3266 f_TC_attach(id);
3267 /* then activate PDP context */
3268 f_pdp_ctx_act(apars);
3269 /* then transceive a downlink PDU */
3270 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3271
3272 /* now suspend GPRS */
3273 f_bssgp_suspend();
3274
3275 d := activate(as_nopaging_ps());
3276
3277 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3278 * nor any related paging requests */
3279 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3280
3281 deactivate(d);
3282}
3283testcase TC_suspend_nopaging() runs on test_CT {
3284 var BSSGP_ConnHdlr vc_conn;
3285 f_init();
3286 f_sleep(1.0);
3287 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3288 vc_conn.done;
3289 f_cleanup();
3290}
3291
3292
3293/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3294private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3295 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3296 var OCT1 susp_ref;
3297 var default d;
3298
3299 /* first perform regular attach */
3300 f_TC_attach(id);
3301 /* then activate PDP context */
3302 f_pdp_ctx_act(apars);
3303 /* then transceive a downlink PDU */
3304 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3305
3306 /* now suspend GPRS */
3307 susp_ref := f_bssgp_suspend();
3308
3309 d := activate(as_nopaging_ps());
3310
3311 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3312 * nor any related paging requests */
3313 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3314
3315 deactivate(d);
3316
3317 /* resume GPRS */
3318 f_bssgp_resume(susp_ref);
3319
3320 /* now data should be flowing again */
3321 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3322}
3323testcase TC_suspend_resume() runs on test_CT {
3324 var BSSGP_ConnHdlr vc_conn;
3325 f_init();
3326 f_sleep(1.0);
3327 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3328 vc_conn.done;
3329 f_cleanup();
3330}
3331
3332/* SUSPEND, then RAU: data expected to flow after implicit resume */
3333private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3334 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3335 var default d;
3336
3337 /* first perform regular attach */
3338 f_TC_attach(id);
3339 /* then activate PDP context */
3340 f_pdp_ctx_act(apars);
3341 /* then transceive a downlink PDU */
3342 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3343
3344 /* now suspend GPRS */
3345 f_bssgp_suspend();
3346
3347 d := activate(as_nopaging_ps());
3348
3349 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3350 * nor any related paging requests */
3351 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3352
3353 deactivate(d);
3354
3355 /* perform RAU (implicit RESUME) */
3356 f_routing_area_update(g_pars.ra);
3357
Harald Welted5836dc2021-03-20 15:40:00 +01003358 /* give SGSN some time to actually receve + process the RAU Complete we sent */
3359 f_sleep(0.5);
3360
Harald Welte8e5932e2020-06-17 22:12:54 +02003361 /* now data should be flowing again */
3362 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3363
3364}
3365testcase TC_suspend_rau() runs on test_CT {
3366 var BSSGP_ConnHdlr vc_conn;
3367 f_init();
3368 f_sleep(1.0);
3369 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3370 vc_conn.done;
3371 f_cleanup();
3372}
3373
3374
3375/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3376private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3377 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3378 var default d;
3379
3380 /* first perform regular attach */
3381 f_TC_attach(id);
3382 /* then activate PDP context */
3383 f_pdp_ctx_act(apars);
3384 /* then transceive a downlink PDU */
3385 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3386
3387 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3388 f_sleep(5.0);
3389
3390 /* now data should be flowing again, but with PS PAGING */
3391 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3392 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3393
3394 /* FIXME: simulate paging response */
3395 /* FIXME: verify PDU actually arrives only after paging response was successful */
3396
3397}
3398testcase TC_paging_ps() runs on test_CT {
3399 var BSSGP_ConnHdlr vc_conn;
3400 f_init();
3401 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3402 f_sleep(1.0);
3403 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3404 vc_conn.done;
3405 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3406 f_cleanup();
3407}
3408
Philipp Maier7df55e02020-12-14 23:46:04 +01003409/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3410 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3411 * other and vice versa. */
3412testcase TC_bssgp_rim_single_report() runs on test_CT {
3413 var BSSGP_ConnHdlr vc_conn;
3414 f_init();
Philipp Maier7df55e02020-12-14 23:46:04 +01003415
3416 timer T := 2.0;
3417
3418 var template RIM_Routing_Address dst_addr;
3419 var template RIM_Routing_Address src_addr;
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003420 var template (value) RAN_Information_Request_RIM_Container req_cont;
3421 var template (value) RAN_Information_RIM_Container res_cont;
3422 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maier7df55e02020-12-14 23:46:04 +01003423 var template PDU_BSSGP bssgp_rim_pdu_expect;
3424
3425 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3426 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003427
3428
Philipp Maier7df55e02020-12-14 23:46:04 +01003429 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3430 * based on the cell id in dst_addr to GB interface #1. */
3431 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3432 ts_RIM_Sequence_Number(1),
3433 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3434 ts_RIM_Protocol_Version_Number(1),
3435 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3436 omit);
3437 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3438 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3439 req_cont);
3440 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3441 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3442 tr_RAN_Information_Request_RIM_Container);
3443 RIM[0].send(bssgp_rim_pdu);
3444 T.start;
3445 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003446 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3447 setverdict(pass);
3448 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003449 [] RIM[1].receive {
3450 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003451 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003452 [] T.timeout {
3453 setverdict(fail, "No BSSGP RIM PDU received");
3454 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003455 }
3456 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003457
Philipp Maier7df55e02020-12-14 23:46:04 +01003458 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3459 * GB interface #0 */
Philipp Maier7df55e02020-12-14 23:46:04 +01003460 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3461 ts_RIM_Sequence_Number(2),
3462 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3463 ts_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003464 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 +01003465 omit);
3466 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3467 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3468 res_cont);
3469 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3470 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3471 ?);
3472 RIM[1].send(bssgp_rim_pdu);
3473 T.start;
3474 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003475 [] RIM[0].receive(bssgp_rim_pdu_expect) {
3476 setverdict(pass);
3477 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003478 [] RIM[0].receive {
3479 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003480 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003481 [] T.timeout {
3482 setverdict(fail, "No BSSGP RIM PDU received");
3483 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003484 }
3485 }
3486
3487 f_cleanup();
3488}
Harald Welte8e5932e2020-06-17 22:12:54 +02003489
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003490testcase TC_rim_eutran_to_geran() runs on test_CT {
3491 var BSSGP_ConnHdlr vc_conn;
3492 f_init();
3493 /* connect RIM related port */
3494 connect(vc_GTP:CLIENT_DEFAULT, self:GTPC);
3495
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01003496 var Gtp1cPeer peer := {
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003497 connId := 1,
3498 remName := mp_sgsn_gtp_ip,
3499 remPort := GTP1C_PORT
3500 }
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003501 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 +02003502
3503 var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
3504 var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
3505 var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
Philipp Maier7e9acc32023-08-04 17:23:12 +02003506 var template (value) RIM_RoutingAddress gtpc_rim_ra;
3507 var template (value) RIM_RoutingAddress_Discriminator gtpc_rim_ra_discr;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003508 var template (value) Gtp1cUnitdata gtpc_pdu;
3509
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003510 gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(gtp_ci);
3511 gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(gtp_ci, tac := 3, gnbid := '12345678123456'O);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003512
3513 gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3514 ts_GTPC_RIM_Sequence_Number(1),
3515 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3516 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003517 tsu_GTPC_RAN_Information_Request_Application_Container_NACC(gtp_ci),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003518 omit);
3519 gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3520 ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3521 gtpc_rim_req_cont);
Philipp Maier7e9acc32023-08-04 17:23:12 +02003522
3523 /* Assemble RIM Routing Address (essentially a copy of the destination cell identifier)*/
3524 gtpc_rim_ra := ts_RIM_RoutingAddress(enc_RIM_Routing_Address_GTPC(valueof(gtpc_dst_addr)));
3525 gtpc_rim_ra_discr := ts_RIM_RoutingAddress_Discriminator(hex2bit(RIM_ADDR_GERAN_CELL_ID));
3526 gtpc_pdu := ts_GTPC_RANInfoRelay(peer, ts_RANTransparentContainer_RAN_INFO_REQ(gtpc_bssgp_cont),
3527 gtpc_rim_ra, gtpc_rim_ra_discr);
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003528 GTPC.send(gtpc_pdu);
3529
3530 var template RIM_Routing_Address bssgp_dst_addr, bssgp_src_addr;
3531 var template PDU_BSSGP bssgp_rim_pdu_expect;
3532 bssgp_dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3533 bssgp_src_addr := t_RIM_Routing_Address_enbid(g_gb[1].cfg.bvc[0].cell_id, tac := 3, gnbid := '12345678123456'O);
3534 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3535 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3536 tr_RAN_Information_Request_RIM_Container);
3537 timer T := 2.0;
3538 T.start;
3539 alt {
3540 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3541 setverdict(pass);
3542 T.stop;
3543 }
3544 [] RIM[1].receive {
3545 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3546 }
3547 [] T.timeout {
3548 setverdict(fail, "No BSSGP RIM PDU received");
3549 mtc.stop;
3550 }
3551 }
3552
3553 /* Now also emulate also the response as well and send it back on GB
3554 interface #1. Expect the result on * GTPC */
Vadim Yanitskiy805d5b12023-06-27 19:30:14 +07003555 var template (value) RAN_Information_RIM_Container res_cont;
3556 var template (value) PDU_BSSGP bssgp_rim_pdu;
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003557 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3558 ts_RIM_Sequence_Number(2),
3559 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3560 ts_RIM_Protocol_Version_Number(1),
3561 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[1].cfg.bvc[0].cell_id, false, 3, si_default)),
3562 omit);
3563 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3564 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3565 res_cont);
3566 RIM[1].send(bssgp_rim_pdu);
3567
3568 var template RAN_Information_RIM_Container_GTPC rim_cont;
3569 var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_cont_ack;
3570 var template Gtp1cUnitdata gtpc_pdu_exp;
3571 rim_cont := tr_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3572 ts_GTPC_RIM_Sequence_Number(2),
3573 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3574 ts_GTPC_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol17e0f8c2021-12-03 15:11:34 +01003575 tru_GTPC_ApplContainer_or_ApplErrContainer_NACC(tru_GTPC_ApplContainer_NACC(gtp_ci, false, 3, si_default)),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003576 omit);
3577 gtpc_bssgp_cont_ack := tr_GTPC_RAN_Information(tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3578 tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3579 rim_cont);
3580 gtpc_pdu_exp := tr_GTPC_RANInfoRelay(peer, tr_RANTransparentContainer_RAN_INFO(gtpc_bssgp_cont_ack));
3581
3582 T.start;
3583 alt {
3584 [] GTPC.receive(gtpc_pdu_exp) {
3585 setverdict(pass);
3586 T.stop;
3587 }
3588 [] GTPC.receive {
3589 setverdict(fail, "Unexpected GTPC RIM PDU received");
3590 }
3591 [] T.timeout {
3592 setverdict(fail, "No GTPC RIM PDU received");
3593 mtc.stop;
3594 }
3595 }
3596
3597 f_cleanup();
3598}
3599
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003600/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3601private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3602 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3603
3604 /* first perform regular attach */
3605 f_gmm_attach(false, false, ran_index := 0);
3606 /* then activate PDP context */
3607 f_pdp_ctx_act(apars, ran_index := 0);
3608 /* then transceive a downlink PDU */
3609 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3610 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3611
3612 /* Now attach on different cell: */
3613 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3614 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3615 g_pars.net.expect_auth := false;
3616 f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0]));
3617 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3618 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1);
3619}
3620testcase TC_cell_change_different_rai_ci_attach() runs on test_CT {
3621 var BSSGP_ConnHdlr vc_conn;
3622 f_init();
3623 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68);
3624 vc_conn.done;
3625 f_cleanup();
3626}
3627
3628/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3629/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3630private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3631 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3632
3633 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3634 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3635
3636 /* first perform regular attach */
3637 f_gmm_attach(false, false, ran_index := 1);
3638 /* then activate PDP context */
3639 f_pdp_ctx_act(apars, ran_index := 1);
3640 /* then transceive a downlink PDU */
3641 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3642 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3643
3644 /* Now attach on different cell: */
3645 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3646 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3647 g_pars.net.expect_auth := false;
3648 f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1]));
3649 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3650 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3651}
3652testcase TC_cell_change_different_ci_attach() runs on test_CT {
3653 var BSSGP_ConnHdlr vc_conn;
3654 f_init();
3655 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69);
3656 vc_conn.done;
3657 f_cleanup();
3658}
3659
3660/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */
3661private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3662 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3663
3664 /* first perform regular attach */
3665 f_gmm_attach(false, false, ran_index := 0);
3666 /* then activate PDP context */
3667 f_pdp_ctx_act(apars, ran_index := 0);
3668 /* then transceive a downlink PDU */
3669 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3670 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3671
3672 /* Send some data over new bvci, it should be silently discarded since
3673 * RAC changed and SGSN expects a RAU to occur in that case */
3674 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3675 var octetstring payload := f_rnd_octstring(200);
3676 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
3677 BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1));
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +01003678 var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003679 timer T := 2.0;
3680 T.start;
3681 alt {
3682 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) {
3683 setverdict(fail, "Unexpected GTP message");
3684 }
3685 [] T.timeout { setverdict(pass); }
3686 }
3687
3688 /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */
3689 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3690 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3691}
3692testcase TC_cell_change_different_rai_ci_data() runs on test_CT {
3693 var BSSGP_ConnHdlr vc_conn;
3694 f_init();
3695 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70);
3696 vc_conn.done;
3697 f_cleanup();
3698}
3699
3700/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */
3701/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3702private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3703 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3704
3705 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3706 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3707
3708 /* first perform regular attach */
3709 f_gmm_attach(false, false, ran_index := 1);
3710 /* then activate PDP context */
3711 f_pdp_ctx_act(apars, ran_index := 1);
3712 /* then transceive a downlink PDU */
3713 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3714 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3715
3716 /* Now attach on different cell: */
3717 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3718 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3719
3720 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3721 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3722}
3723testcase TC_cell_change_different_ci_data() runs on test_CT {
3724 var BSSGP_ConnHdlr vc_conn;
3725 f_init();
3726 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71);
3727 vc_conn.done;
3728 f_cleanup();
3729}
3730
Vadim Yanitskiyacd0b392024-04-06 05:38:35 +07003731/* SGSN terminated SGSN Context Request procedure (we request, SGSN responds)
3732 * 3GPP TS 23.401, Figure D.3.6-1: "Gn/Gp SGSN to MME Tracking Area Update procedure" */
3733private function f_TC_sgsn_context_req_in(charstring id) runs on BSSGP_ConnHdlr {
3734 var integer seq_nr := f_rnd_int(65535);
3735 var Gtp1cUnitdata gtpc_ud;
3736 timer T;
3737
3738 var Gtp1cPeer peer := {
3739 connId := 1,
3740 remName := mp_sgsn_gtp_ip,
3741 remPort := GTP1C_PORT
3742 }
3743
3744 /* The MS attaches to GERAN/UTRAN and enjoys the service */
3745 f_gmm_attach(false, false);
3746
3747 /* The MS switches to an LTE cell and performs Tracking Area Update Request there.
3748 * The MME requests information about the MS by sending SGSN Context Request. */
3749 var template (value) GTPC_PDUs ctx_req;
3750 ctx_req := ts_SGSNContextReqPDU(rai := ts_RoutingAreaIdentity('250'H, 'F99'H, '4242'O, 'DE'O),
3751 teic := '12345678'O,
3752 sgsn_addr_control := f_inet_addr(mp_ggsn_ip),
3753 ptmsi := ts_PTMSI(g_pars.p_tmsi),
3754 ptmsi_sig := ts_PTMSI_sig('010203'O));
3755 GTP.send(ts_GTPC_SGSNContextReq(peer, seq_nr, ctx_req));
3756
3757 /* The SGSN responds with subscriber's IMSI */
3758 var template (present) GTPC_PDUs ctx_rsp;
3759 ctx_rsp := tr_SGSNContextRespPDU(cause := GTP_CAUSE_REQUEST_ACCEPTED,
3760 imsi := g_pars.imsi);
Vadim Yanitskiy74b12c72024-04-19 01:46:07 +07003761
3762 /* SGSN Address for Control Plane */
3763 var octetstring sgsn_addr := f_inet_addr(mp_sgsn_gtp_ip);
3764 ctx_rsp.sgsn_ContextResponse.sgsn_addr_controlPlane := tr_GsnAddr(sgsn_addr);
3765
3766 /* Match MM Context */
3767 if (ispresent(g_pars.vec)) {
3768 /* XXX: this is only valid for GERAN */
3769 var octetstring triplet := g_pars.vec.rand & g_pars.vec.sres & g_pars.vec.kc;
3770 ctx_rsp.sgsn_ContextResponse.mm_Context := tr_MM_ContextGSM(kc := g_pars.vec.kc,
3771 triplet := triplet);
3772 /* TODO: 7.5.4 "The IMEISV shall, if available, be included in the MM Context".
3773 * See also 3GPP TS 29.060, section 7.7.28 and Table 47A */
3774 }
3775
3776 /* TODO: match PDP Context */
Vadim Yanitskiyacd0b392024-04-06 05:38:35 +07003777
3778 T.start(2.0);
3779 alt {
3780 [] GTP.receive(tr_GTPC_SGSNContextResp(?, ?, ctx_rsp)) -> value gtpc_ud {
3781 log("Rx SGSN Context Resp from SGSN, sending Ack");
3782 GTP.send(ts_GTPC_SGSNContextAck(gtpc_ud.peer, '12345678'O, seq_nr));
3783 setverdict(pass);
3784 }
3785 [] GTP.receive(tr_GTPC_SGSNContextResp) -> value gtpc_ud {
3786 GTP.send(ts_GTPC_SGSNContextAck(gtpc_ud.peer, '12345678'O, seq_nr,
3787 ts_SGSNContextAckPDU(GTP_CAUSE_INVALID_MSG_FORMAT)));
3788 setverdict(fail, "Rx unexpected SGSN Context Resp");
3789 }
3790 [] T.timeout {
3791 setverdict(fail, "Timeout waiting for SGSN Context Resp");
3792 }
3793 }
3794
3795 /* HLR/HSS tells SGSN to forget this MS/UE */
3796 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
3797 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
3798}
3799testcase TC_sgsn_context_req_in() runs on test_CT {
3800 var BSSGP_ConnHdlr vc_conn;
3801 f_init();
3802 f_sleep(1.0);
3803 vc_conn := f_start_handler(refers(f_TC_sgsn_context_req_in), testcasename(), g_gb, 72);
3804 vc_conn.done;
3805 f_cleanup();
3806}
3807
3808/* SGSN originated SGSN Context Request procedure (SGSN requests, we respond)
3809 * 3GPP TS 23.401, Figure D.3.5-1 "Routing Area Update procedure" */
3810private function f_TC_sgsn_context_req_out(charstring id) runs on BSSGP_ConnHdlr {
3811 var integer seq_nr := f_rnd_int(65535);
3812 var Gtp1cUnitdata gtpc_ud;
3813 timer T;
3814
3815 /* The MS goes to GERAN/UTRAN from an LTE cell */
3816 f_send_l3(ts_GMM_RAU_REQ(mi_lv := valueof(ts_MI_TMSI_LV('DE42DE42'O)),
3817 upd_type := GPRS_UPD_T_RA,
3818 old_ra := f_random_RAI()), 0);
3819
3820
3821 /* The SGSN has no idea about the MS and inquires the MME about it */
3822 T.start(2.0);
3823 alt {
3824 [] GTP.receive(tr_GTPC_SGSNContextReq(?, ?)) -> value gtpc_ud {
3825 log("Rx SGSN Context Req from SGSN");
3826 setverdict(pass);
3827 T.stop;
3828 }
3829 [] GTP.receive(tr_GTPC_SGSNContextResp) {
3830 setverdict(fail, "Rx unexpected SGSN Context Req");
3831 mtc.stop;
3832 }
3833 [] BSSGP[0].receive(tr_LLC_XID_MT_CMD(?, ?)) {
3834 /* Ignore XID Reset */
3835 repeat;
3836 }
3837 [] BSSGP[0].receive(tr_GMM_RAU_REJECT) {
3838 /* osmo-sgsn -latest would send RAU Reject (Implicitly detached) */
3839 setverdict(fail, "Rx unexpected RAU Reject");
3840 mtc.stop;
3841 }
3842 [] T.timeout {
3843 setverdict(fail, "Timeout waiting for SGSN Context Req");
3844 mtc.stop;
3845 }
3846 }
3847
3848 /* The MME responds */
3849 var OCT8 kc := f_rnd_octstring(8);
3850
3851 var template (value) PDP_Context_GTPC pdp_ctx;
3852 pdp_ctx := ts_PDP_Context_GTPC(pdp_addr := f_inet_addr("10.10.10.10"),
3853 ggsn_gsn_addr := f_inet_addr(mp_ggsn_ip),
3854 apn := '08696E7465726E6574'O);
3855
3856 var template (value) GTPC_PDUs ctx_rsp;
3857 ctx_rsp := ts_SGSNContextRespPDU(cause := GTP_CAUSE_REQUEST_ACCEPTED,
3858 imsi := g_pars.imsi,
3859 teic := '12345678'O,
3860 mm_context := ts_MM_ContextGSM(kc),
3861 pdp_ctx_list := { pdp_ctx });
3862 GTP.send(ts_GTPC_SGSNContextResp(gtpc_ud.peer, '12345678'O, seq_nr, ctx_rsp));
3863
3864 /* TODO: Security Functions (auth/ciphering?) */
3865
3866 /* The SGSN ACKs */
3867 T.start(2.0);
3868 alt {
3869 [] GTP.receive(tr_GTPC_SGSNContextAck) -> value gtpc_ud {
3870 log("Rx SGSN Context ACK from SGSN");
3871 setverdict(pass);
3872 T.stop;
3873 }
3874 [] T.timeout {
3875 setverdict(fail, "Timeout waiting for SGSN Contect ACK");
3876 mtc.stop;
3877 }
3878 }
3879
3880 /* TODO: Update PDP Context Req/Resp */
3881 /* TODO: 7..10 Update Location, ISD */
3882
3883 /* RAU procedure completion */
3884 T.start(2.0);
3885 alt {
3886 [] as_routing_area_update_gb(0) {
3887 log("RAU procedure completed");
3888 setverdict(pass);
3889 T.stop;
3890 }
3891 [] BSSGP[0].receive { repeat; }
3892 [] T.timeout {
3893 setverdict(fail, "Timeout completing the RAU procedure");
3894 mtc.stop;
3895 }
3896 }
3897}
3898testcase TC_sgsn_context_req_out() runs on test_CT {
3899 var BSSGP_ConnHdlr vc_conn;
3900 f_init();
3901 f_sleep(1.0);
3902 vc_conn := f_start_handler(refers(f_TC_sgsn_context_req_out), testcasename(), g_gb, 73);
3903 vc_conn.done;
3904 f_cleanup();
3905}
3906
Harald Welte5ac31492018-02-15 20:39:13 +01003907control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003908 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003909 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003910 execute( TC_attach_umts_aka_umts_res() );
3911 execute( TC_attach_umts_aka_gsm_sres() );
arehbein3ede9e32023-02-06 21:02:53 +01003912 execute( TC_attach_timeout_after_pdp_act() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003913 execute( TC_attach_auth_id_timeout() );
3914 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003915 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003916 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003917 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003918 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003919 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003920 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003921 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003922 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003923 execute( TC_attach_closed_add_vty(), 20.0 );
3924 execute( TC_attach_check_subscriber_list(), 20.0 );
3925 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003926 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003927 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3928 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3929 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3930 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003931 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003932 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003933 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003934 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003935 execute( TC_attach_usim_resync() );
Eric Wildc555be52021-05-15 19:48:22 +02003936 execute( TC_attach_usim_a54_a54() );
3937 execute( TC_attach_usim_a54_a53() );
3938 execute( TC_attach_usim_a53_a54() );
3939 execute( TC_attach_usim_a50_a54() );
3940 execute( TC_attach_usim_a54_a50() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003941 execute( TC_detach_unknown_nopoweroff() );
3942 execute( TC_detach_unknown_poweroff() );
3943 execute( TC_detach_nopoweroff() );
3944 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003945 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003946 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003947 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003948 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003949 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003950 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003951 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003952 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003953 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003954 execute( TC_attach_restart_ctr_echo() );
3955 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003956 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003957 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3958 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003959 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003960 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003961 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003962
Harald Welte2aaac1b2019-05-02 10:02:53 +02003963 execute( TC_xid_empty_l3() );
3964 execute( TC_xid_n201u() );
3965
Harald Weltea05b8072019-04-23 22:35:05 +02003966 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003967 execute( TC_llc_sabm_dm_llgmm() );
3968 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003969
Harald Welte8e5932e2020-06-17 22:12:54 +02003970 execute( TC_suspend_nopaging() );
3971 execute( TC_suspend_resume() );
3972 execute( TC_suspend_rau() );
3973 execute( TC_paging_ps() );
3974
Philipp Maier7df55e02020-12-14 23:46:04 +01003975 execute( TC_bssgp_rim_single_report() );
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003976 execute( TC_rim_eutran_to_geran() );
Philipp Maier7df55e02020-12-14 23:46:04 +01003977
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003978 execute( TC_cell_change_different_rai_ci_attach() );
3979 execute( TC_cell_change_different_rai_ci_data() );
3980 execute( TC_cell_change_different_ci_attach() );
3981 execute( TC_cell_change_different_ci_data() );
3982
Vadim Yanitskiyacd0b392024-04-06 05:38:35 +07003983 execute( TC_sgsn_context_req_in() );
3984 execute( TC_sgsn_context_req_out() );
3985
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003986 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3987 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003988}
Harald Welte96a33b02018-02-04 10:36:22 +01003989
3990
3991
3992}