blob: ec18b5306f1a30b6d39d1bd65205603c53e2c327 [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;
15
Harald Welte96a33b02018-02-04 10:36:22 +010016import from General_Types all;
17import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020018import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010019import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010020import from NS_Types all;
21import from NS_Emulation all;
22import from BSSGP_Types all;
23import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010024import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020025import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010026
27import from MobileL3_CommonIE_Types all;
28import from MobileL3_GMM_SM_Types all;
29import from MobileL3_Types all;
30import from L3_Templates all;
31import from L3_Common all;
32
33import from GSUP_Emulation all;
34import from GSUP_Types all;
35import from IPA_Emulation all;
36
Harald Welte26fbb6e2019-04-14 17:32:46 +020037import from RAN_Adapter all;
38import from RAN_Emulation all;
39import from RANAP_Templates all;
40import from RANAP_PDU_Descriptions all;
41import from RANAP_IEs all;
42
Harald Welteeded9ad2018-02-17 20:57:34 +010043import from GTP_Emulation all;
44import from GTP_Templates all;
45import from GTP_CodecPort all;
46import from GTPC_Types all;
47import from GTPU_Types all;
48
Harald Weltea2526a82018-02-18 19:03:36 +010049import from LLC_Types all;
50import from LLC_Templates all;
51
52import from SNDCP_Types all;
53
Harald Weltebd194722018-02-16 22:11:08 +010054import from TELNETasp_PortType all;
55import from Osmocom_VTY_Functions all;
56
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010057import from GSM_RR_Types all;
58
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020059import from MobileL3_MM_Types all;
60
Harald Welteeded9ad2018-02-17 20:57:34 +010061
Harald Welte5ac31492018-02-15 20:39:13 +010062modulepar {
63 /* IP/port on which we run our internal GSUP/HLR emulation */
64 charstring mp_hlr_ip := "127.0.0.1";
65 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010066 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020067 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020068
Alexander Couzensf3c1b412018-08-24 00:42:51 +020069 NSConfigurations mp_nsconfig := {
70 {
71 local_udp_port := 21010,
72 local_ip := "127.0.0.1",
73 remote_udp_port := 23000,
74 remote_ip := "127.0.0.1",
75 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020076 nsei := 96,
77 role_sgsn := false,
78 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020079 },
80 {
81 local_udp_port := 21011,
82 local_ip := "127.0.0.1",
83 remote_udp_port := 23000,
84 remote_ip := "127.0.0.1",
85 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020086 nsei := 97,
87 role_sgsn := false,
88 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020089 },
90 {
91 local_udp_port := 21012,
92 local_ip := "127.0.0.1",
93 remote_udp_port := 23000,
94 remote_ip := "127.0.0.1",
95 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020096 nsei := 98,
97 role_sgsn := false,
98 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020099 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200100 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200101
102 RAN_Configurations mp_ranap_cfg := {
103 {
104 transport := RANAP_TRANSPORT_IuCS,
105 sccp_service_type := "mtp3_itu",
106 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
107 own_pc := 195,
108 own_ssn := 142,
109 peer_pc := 188, /* 0.23.4 */
110 peer_ssn := 142,
111 sio := '83'O,
112 rctx := 2
113 }
114 }
Harald Welte5ac31492018-02-15 20:39:13 +0100115};
116
117type record GbInstance {
118 NS_CT vc_NS,
119 BSSGP_CT vc_BSSGP,
120 BssgpConfig cfg
121};
Harald Welte96a33b02018-02-04 10:36:22 +0100122
Harald Welte2fa771f2019-05-02 20:13:53 +0200123const integer NUM_GB := 3;
124type record length(NUM_GB) of GbInstance GbInstances;
125type record length(NUM_GB) of NSConfiguration NSConfigurations;
126type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200127
Harald Welte26fbb6e2019-04-14 17:32:46 +0200128const integer NUM_RNC := 1;
129type record of RAN_Configuration RAN_Configurations;
130
Harald Welte96a33b02018-02-04 10:36:22 +0100131type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200132 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200133 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200134 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100135
Harald Welte5ac31492018-02-15 20:39:13 +0100136 var GSUP_Emulation_CT vc_GSUP;
137 var IPA_Emulation_CT vc_GSUP_IPA;
138 /* only to get events from IPA underneath GSUP */
139 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100140
Harald Welteeded9ad2018-02-17 20:57:34 +0100141 var GTP_Emulation_CT vc_GTP;
142
Harald Weltebd194722018-02-16 22:11:08 +0100143 port TELNETasp_PT SGSNVTY;
144
Harald Welte96a33b02018-02-04 10:36:22 +0100145 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200146 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100147};
148
Harald Welte26fbb6e2019-04-14 17:32:46 +0200149type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100150 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100151 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200152 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100153}
154
155type record SGSN_ConnHdlrNetworkPars {
156 boolean expect_ptmsi,
157 boolean expect_auth,
158 boolean expect_ciph
159};
160
161type record BSSGP_ConnHdlrPars {
162 /* IMEI of the simulated ME */
163 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200164 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100165 hexstring imsi,
166 /* MSISDN of the simulated MS (probably unused) */
167 hexstring msisdn,
168 /* P-TMSI allocated to the simulated MS */
169 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100170 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100171 /* TLLI of the simulated MS */
172 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100173 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100174 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200175 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200176 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
177 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100178 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100179 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200180 float t_guard,
181 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200182 SCCP_PAR_Address sccp_addr_local optional,
183 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100184};
185
Alexander Couzens89508702018-07-31 04:16:10 +0200186private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200187 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200188 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
189
190 var RoutingAreaIdentificationV ret := {
191 mccDigit1 := mcc_mnc[0],
192 mccDigit2 := mcc_mnc[1],
193 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200194 mncDigit3 := mcc_mnc[3],
195 mncDigit1 := mcc_mnc[4],
196 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200197 lac := int2oct(cell_id.ra_id.lai.lac, 16),
198 rac := int2oct(cell_id.ra_id.rac, 8)
199 }
200 return ret;
201};
202
Alexander Couzens51114d12018-07-31 18:41:56 +0200203private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
204 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
205 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100206 /* connect lower end of BSSGP emulation with NS upper port */
207 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
208 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
209 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
210
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200211 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100212 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
213}
214
215private function f_init_gsup(charstring id) runs on test_CT {
216 id := id & "-GSUP";
217 var GsupOps ops := {
218 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
219 };
220
221 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
222 vc_GSUP := GSUP_Emulation_CT.create(id);
223
224 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
225 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
226 /* we use this hack to get events like ASP_IPA_EVENT_UP */
227 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
228
229 vc_GSUP.start(GSUP_Emulation.main(ops, id));
230 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
231
232 /* wait for incoming connection to GSUP port before proceeding */
233 timer T := 10.0;
234 T.start;
235 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700236 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100237 [] T.timeout {
238 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200239 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100240 }
241 }
242}
243
Harald Welteeded9ad2018-02-17 20:57:34 +0100244private function f_init_gtp(charstring id) runs on test_CT {
245 id := id & "-GTP";
246
247 var GtpEmulationCfg gtp_cfg := {
248 gtpc_bind_ip := mp_ggsn_ip,
249 gtpc_bind_port := GTP1C_PORT,
250 gtpu_bind_ip := mp_ggsn_ip,
251 gtpu_bind_port := GTP1U_PORT,
252 sgsn_role := false
253 };
254
255 vc_GTP := GTP_Emulation_CT.create(id);
256 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
257}
258
Harald Weltebd194722018-02-16 22:11:08 +0100259private function f_init_vty() runs on test_CT {
260 map(self:SGSNVTY, system:SGSNVTY);
261 f_vty_set_prompts(SGSNVTY);
262 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200263 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100264 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
265}
266
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200267private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
268 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200269 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200270 } else {
271 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
272 }
273}
274
Harald Weltebd194722018-02-16 22:11:08 +0100275
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200276/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
277function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200278 var integer i;
279
Harald Welte96a33b02018-02-04 10:36:22 +0100280 if (g_initialized == true) {
281 return;
282 }
283 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100284 g_gb[0].cfg := {
285 nsei := 96,
286 bvci := 196,
287 cell_id := {
288 ra_id := {
289 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100290 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100291 rac := 0
292 },
293 cell_id := 20960
294 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200295 sgsn_role := false,
296 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100297 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200298 g_gb[1].cfg := {
299 nsei := 97,
300 bvci := 210,
301 cell_id := {
302 ra_id := {
303 lai := {
304 mcc_mnc := mcc_mnc, lac := 13200},
305 rac := 0
306 },
307 cell_id := 20961
308 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200309 sgsn_role := false,
310 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200311 };
312 g_gb[2].cfg := {
313 nsei := 98,
314 bvci := 220,
315 cell_id := {
316 ra_id := {
317 lai := {
318 mcc_mnc := mcc_mnc, lac := 13300},
319 rac := 0
320 },
321 cell_id := 20962
322 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200323 sgsn_role := false,
324 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200325 };
Harald Welte96a33b02018-02-04 10:36:22 +0100326
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200327 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200328 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
329 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
330 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200331
Alexander Couzens1552e792019-07-23 20:38:39 +0200332 if (g_ranap_enable) {
333 for (i := 0; i < NUM_RNC; i := i+1) {
334 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
335 f_ran_adapter_start(g_ranap[i]);
336 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200337 }
Harald Welte5ac31492018-02-15 20:39:13 +0100338 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100339 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200340 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100341}
Harald Welte96a33b02018-02-04 10:36:22 +0100342
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200343function f_cleanup() runs on test_CT {
344 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200345 if (g_ranap_enable) {
346 for (i := 0; i < NUM_RNC; i := i+1) {
347 f_ran_adapter_cleanup(g_ranap[i]);
348 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200349 }
350 self.stop;
351}
352
Harald Welte26fbb6e2019-04-14 17:32:46 +0200353private function RncUnitdataCallback(RANAP_PDU ranap)
354runs on RAN_Emulation_CT return template RANAP_PDU {
355 var template RANAP_PDU resp := omit;
356
357 log ("RANAP_RncUnitDataCallback");
358 /* answer all RESET with RESET ACK */
359 if (match(ranap, tr_RANAP_Reset)) {
360 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
361 var CN_DomainIndicator dom;
362 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
363 resp := ts_RANAP_ResetAck(dom);
364 }
365 return resp;
366}
367
368const RanOps RNC_RanOps := {
369 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
370 ranap_unitdata_cb := refers(RncUnitdataCallback),
371 ps_domain := true,
372 decode_dtap := true,
373 role_ms := true,
374 protocol := RAN_PROTOCOL_RANAP,
375 transport := RANAP_TRANSPORT_IuCS,
376 use_osmux := false,
377 sccp_addr_local := omit,
378 sccp_addr_peer := omit
379};
380
Harald Welte5ac31492018-02-15 20:39:13 +0100381type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
382
383/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200384function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100385 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100386runs on test_CT return BSSGP_ConnHdlr {
387 var BSSGP_ConnHdlr vc_conn;
388 var SGSN_ConnHdlrNetworkPars net_pars := {
389 expect_ptmsi := true,
390 expect_auth := true,
391 expect_ciph := false
392 };
393 var BSSGP_ConnHdlrPars pars := {
394 imei := f_gen_imei(imsi_suffix),
395 imsi := f_gen_imsi(imsi_suffix),
396 msisdn := f_gen_msisdn(imsi_suffix),
397 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100398 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100399 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100400 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100401 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200402 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200403 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100404 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100405 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200406 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200407 sccp_addr_local := omit,
408 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100409 };
410
Alexander Couzens1552e792019-07-23 20:38:39 +0200411 if (g_ranap_enable) {
412 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
413 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
414 }
415
Harald Welte5ac31492018-02-15 20:39:13 +0100416 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200417 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200418 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200419 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
420 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200421 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200422 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
423 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200424 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200425 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100426
Harald Welte26fbb6e2019-04-14 17:32:46 +0200427 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200428 if (g_ranap_enable) {
429 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
430 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
431 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200432
Harald Welte5ac31492018-02-15 20:39:13 +0100433 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
434 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
435
Harald Welteeded9ad2018-02-17 20:57:34 +0100436 connect(vc_conn:GTP, vc_GTP:CLIENT);
437 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
438
Harald Welte5ac31492018-02-15 20:39:13 +0100439 vc_conn.start(f_handler_init(fn, id, pars));
440 return vc_conn;
441}
442
Harald Welte62e29582018-02-16 21:17:11 +0100443private altstep as_Tguard() runs on BSSGP_ConnHdlr {
444 [] g_Tguard.timeout {
445 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200446 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100447 }
448}
449
Harald Welte5ac31492018-02-15 20:39:13 +0100450/* first function called in every ConnHdlr */
451private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
452runs on BSSGP_ConnHdlr {
453 /* do some common stuff like setting up g_pars */
454 g_pars := pars;
455
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200456 llc := f_llc_create(false);
457
Harald Welte5ac31492018-02-15 20:39:13 +0100458 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200459 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100460 /* tell GSUP dispatcher to send this IMSI to us */
461 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100462 /* tell GTP dispatcher to send this IMSI to us */
463 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100464
Harald Welte62e29582018-02-16 21:17:11 +0100465 g_Tguard.start(pars.t_guard);
466 activate(as_Tguard());
467
Harald Welte5ac31492018-02-15 20:39:13 +0100468 /* call the user-supplied test case function */
469 fn.apply(id);
470 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100471}
472
473/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100474 * Detach without Attach
475 * SM procedures without attach / RAU
476 * ATTACH / RAU
477 ** with / without authentication
478 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100479 * re-transmissions of LLC frames
480 * PDP Context activation
481 ** with different GGSN config in SGSN VTY
482 ** with different PDP context type (v4/v6/v46)
483 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100484 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100485 */
486
487testcase TC_wait_ns_up() runs on test_CT {
488 f_init();
489 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200490 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100491}
492
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200493friend function is_gb(integer ran_index) return boolean {
494 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200495}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200496friend function is_iu(integer ran_index) return boolean {
497 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200498}
499
Alexander Couzens0507ec32019-09-15 22:41:22 +0200500function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200501 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200502 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 +0200503}
504
Alexander Couzens0507ec32019-09-15 22:41:22 +0200505private 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 +0200506 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
507 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
508 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200509 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200510}
511
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200512/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
513function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
514 log("Sending InitialUE: ", l3_mo);
515 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
516 var RANAP_PDU ranap;
517 var LAI lai := {
518 pLMNidentity := '62F224'O,
519 lAC := '1234'O,
520 iE_Extensions := omit
521 };
522 var SAI sai := {
523 pLMNidentity := lai.pLMNidentity,
524 lAC := lai.lAC,
525 sAC := '0000'O, /* FIXME */
526 iE_Extensions := omit
527 };
528 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
529 var GlobalRNC_ID grnc_id := {
530 pLMNidentity := lai.pLMNidentity,
531 rNC_ID := 2342 /* FIXME */
532 };
533
534 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
535 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
536 alt {
537 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
538 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
539 setverdict(fail, "DISC.ind from SCCP");
540 mtc.stop;
541 }
542 }
543}
544
545/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200546function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
547 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200548 if (g_pars.rnc_send_initial_ue) {
549 g_pars.rnc_send_initial_ue := false;
550 f_send_l3_initial_ue(l3_mo);
551 } else {
552 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
553 }
554 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200555 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200556 }
557}
558
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200559altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700560 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200561 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100562 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200563 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100564 repeat;
565 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200566 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200567 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200568 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200569 repeat;
570 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200571 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100572 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200573 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200574 repeat;
575 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200576 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200577 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200578 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100579 repeat;
580 }
581}
Harald Welte96a33b02018-02-04 10:36:22 +0100582
Harald Welteca362462019-05-02 20:11:21 +0200583/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200584function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200585runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200586 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200587 var PDU_L3_SGSN_MS l3_mt;
588 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200589 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
590 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200591 l3_mt := mt.dtap;
592 }
Harald Welteca362462019-05-02 20:11:21 +0200593 }
594 return l3_mt;
595}
596
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200597/* perform GMM authentication (if expected).
598 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
599 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200600function 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 +0100601 var PDU_L3_MS_SGSN l3_mo;
602 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200603 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100604 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200605 var GSUP_IE auth_tuple;
606 var template AuthenticationParameterAUTNTLV autn;
607
608 if (umts_aka_challenge) {
609 g_pars.vec := f_gen_auth_vec_3g();
610 autn := {
611 elementIdentifier := '28'O,
612 lengthIndicator := lengthof(g_pars.vec.autn),
613 autnValue := g_pars.vec.autn
614 };
615
616 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
617 g_pars.vec.sres,
618 g_pars.vec.kc,
619 g_pars.vec.ik,
620 g_pars.vec.ck,
621 g_pars.vec.autn,
622 g_pars.vec.res));
623 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
624 } else {
625 g_pars.vec := f_gen_auth_vec_2g();
626 autn := omit;
627 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
628 g_pars.vec.sres,
629 g_pars.vec.kc));
630 log("GSUP sends only 2G auth tuple", auth_tuple);
631 }
Harald Welteca362462019-05-02 20:11:21 +0200632
Harald Welte5ac31492018-02-15 20:39:13 +0100633 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
634 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200635
636 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
637 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200638 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100639 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200640 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
641
642 if (umts_aka_challenge and not force_gsm_sres) {
643 /* set UMTS response instead */
644 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
645 valueField := substr(g_pars.vec.res, 0, 4)
646 };
647 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
648 elementIdentifier := '21'O,
649 lengthIndicator := lengthof(g_pars.vec.res) - 4,
650 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
651 };
652 }
653
654 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100655 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
656 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
657 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
658 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
659 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200660 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200661
662 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200663 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200664 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
665 key_sts := ?)) {
666 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
667 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200668 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200669 }
670 }
Harald Welte76dee092018-02-16 22:12:59 +0100671 } else {
672 /* wait for identity procedure */
673 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100674 }
Harald Welte76dee092018-02-16 22:12:59 +0100675
Harald Welte5ac31492018-02-15 20:39:13 +0100676 deactivate(di);
677}
678
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200679function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100680 g_pars.p_tmsi := p_tmsi;
681 /* update TLLI */
682 g_pars.tlli_old := g_pars.tlli;
683 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100684 if (is_gb(ran_index)) {
685 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
686 }
Harald Weltef70997d2018-02-17 10:11:19 +0100687}
688
Harald Welte04683d02018-02-16 22:43:45 +0100689function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
690 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100691 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200692 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100693 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200694 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200695 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100696 }
Harald Welte04683d02018-02-16 22:43:45 +0100697 g_pars.ra := aa.routingAreaIdentification;
698 if (ispresent(aa.allocatedPTMSI)) {
699 if (not g_pars.net.expect_ptmsi) {
700 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200701 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100702 }
Harald Weltef70997d2018-02-17 10:11:19 +0100703 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100704 }
705 if (ispresent(aa.msIdentity)) {
706 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200707 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100708 }
709 /* P-TMSI.sig */
710 if (ispresent(aa.ptmsiSignature)) {
711 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
712 }
713 /* updateTimer */
714 // aa.readyTimer
715 /* T3302, T3319, T3323, T3312_ext, T3324 */
716}
717
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200718function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100719 /* mandatory IE */
720 g_pars.ra := ra.routingAreaId;
721 if (ispresent(ra.allocatedPTMSI)) {
722 if (not g_pars.net.expect_ptmsi) {
723 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200724 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100725 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200726 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100727 }
728 if (ispresent(ra.msIdentity)) {
729 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200730 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100731 }
732 /* P-TMSI.sig */
733 if (ispresent(ra.ptmsiSignature)) {
734 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
735 }
736 /* updateTimer */
737 // aa.readyTimer
738 /* T3302, T3319, T3323, T3312_ext, T3324 */
739}
740
741
Harald Welte5a4fa042018-02-16 20:59:21 +0100742function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
743 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
744}
745
Harald Welte23178c52018-02-17 09:36:33 +0100746/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700747private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100748 if (ispresent(g_pars.p_tmsi)) {
749 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
750 } else {
751 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
752 }
753}
754
Harald Welte311ec272018-02-17 09:40:03 +0100755private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100756 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100757 /* Expect MSC to perform LU with HLR */
758 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100759 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
760 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
761 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100762 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
763 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
764}
765
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200766friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100767 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200768 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welteca362462019-05-02 20:11:21 +0200769 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100770
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200771 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
772 * 3G auth vectors */
773 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
774 /* The thing is, if the solSACapability is 'omit', then the
775 * revisionLevelIndicatior is at the wrong place! */
776 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
777
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200778 f_send_l3(attach_req, ran_index);
779 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200780 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100781 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100782
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200783 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200784 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
785
Harald Welte04683d02018-02-16 22:43:45 +0100786 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200787 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200788
789 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200790 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200791 as_iu_release_compl_disc();
792 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200793
794 /* Race condition
795 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
796 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
797 * arrived before it. This results in a test case failure.
798 * Delay execution by 50 ms
799 */
800 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200801}
802
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200803friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
804 timer T := 5.0;
805 var PDU_BSSGP rx_pdu;
806 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
807 T.start;
808 alt {
809 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
810 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
811 }
812 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
813 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
814 mtc.stop;
815 }
816 [] T.timeout {
817 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
818 mtc.stop;
819 }
820 }
821 return '00'O;
822}
823
824friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
825 timer T := 5.0;
826 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
827 T.start;
828 alt {
829 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
830 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
831?)) {
832 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
833 mtc.stop;
834 }
835 [] T.timeout {
836 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
837 mtc.stop;
838 }
839 }
840}
841
842
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200843private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
844 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100845 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100846}
847
848testcase TC_attach() runs on test_CT {
849 var BSSGP_ConnHdlr vc_conn;
850 f_init();
851 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200852 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100853 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200854 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100855}
856
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100857testcase TC_attach_mnc3() runs on test_CT {
858 var BSSGP_ConnHdlr vc_conn;
859 f_init('023042'H);
860 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200861 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100862 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200863 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100864}
865
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200866private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
867 f_gmm_attach(true, false);
868 setverdict(pass);
869}
870testcase TC_attach_umts_aka_umts_res() runs on test_CT {
871 var BSSGP_ConnHdlr vc_conn;
872 f_init();
873 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200874 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200875 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200876 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200877}
878
879private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
880 f_gmm_attach(true, true);
881 setverdict(pass);
882}
883testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
884 var BSSGP_ConnHdlr vc_conn;
885 f_init();
886 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200887 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200888 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200889 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200890}
891
Harald Welte5b7c8122018-02-16 21:48:17 +0100892/* MS never responds to ID REQ, expect ATTACH REJECT */
893private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100894 var RoutingAreaIdentificationV old_ra := f_random_RAI();
895
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200896 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100897 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200898 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100899 /* don't send ID Response */
900 repeat;
901 }
Harald Welte955aa942019-05-03 01:29:29 +0200902 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100903 setverdict(pass);
904 }
Harald Welte955aa942019-05-03 01:29:29 +0200905 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100906 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200907 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100908 }
909 }
910}
911testcase TC_attach_auth_id_timeout() runs on test_CT {
912 var BSSGP_ConnHdlr vc_conn;
913 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200914 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 +0100915 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200916 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100917}
918
919/* HLR never responds to SAI REQ, expect ATTACH REJECT */
920private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100921 var RoutingAreaIdentificationV old_ra := f_random_RAI();
922
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200923 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100924 alt {
925 [] as_mm_identity();
926 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
927 }
928 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200929 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100930 setverdict(pass);
931}
932testcase TC_attach_auth_sai_timeout() runs on test_CT {
933 var BSSGP_ConnHdlr vc_conn;
934 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200935 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100936 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200937 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100938}
939
Harald Weltefe253882018-02-17 09:25:00 +0100940/* HLR rejects SAI, expect ATTACH REJECT */
941private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100942 var RoutingAreaIdentificationV old_ra := f_random_RAI();
943
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200944 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100945 alt {
946 [] as_mm_identity();
947 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
948 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
949 }
950 }
Harald Welte955aa942019-05-03 01:29:29 +0200951 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100952 setverdict(pass);
953}
954testcase TC_attach_auth_sai_reject() runs on test_CT {
955 var BSSGP_ConnHdlr vc_conn;
956 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200957 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100958 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200959 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100960}
961
Harald Welte5b7c8122018-02-16 21:48:17 +0100962/* HLR never responds to UL REQ, expect ATTACH REJECT */
963private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200964 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100965 var RoutingAreaIdentificationV old_ra := f_random_RAI();
966
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200967 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100968 f_gmm_auth();
969 /* Expect MSC to perform LU with HLR */
970 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
971 /* Never follow-up with ISD_REQ or UL_RES */
972 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200973 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100974 setverdict(pass);
975 }
Harald Welte955aa942019-05-03 01:29:29 +0200976 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
977 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100978 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200979 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100980 }
981 }
982}
983testcase TC_attach_gsup_lu_timeout() runs on test_CT {
984 var BSSGP_ConnHdlr vc_conn;
985 f_init();
986 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200987 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100988 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200989 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100990}
991
Harald Welteb7c14e92018-02-17 09:29:16 +0100992/* HLR rejects UL REQ, expect ATTACH REJECT */
993private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200994 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100995 var RoutingAreaIdentificationV old_ra := f_random_RAI();
996
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200997 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100998 f_gmm_auth();
999 /* Expect MSC to perform LU with HLR */
1000 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1001 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1002 }
1003 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001004 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001005 setverdict(pass);
1006 }
Harald Welte955aa942019-05-03 01:29:29 +02001007 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1008 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001009 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001010 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001011 }
1012 }
1013}
1014testcase TC_attach_gsup_lu_reject() 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_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001019 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001020 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001021}
1022
1023
Harald Welte3823e2e2018-02-16 21:53:48 +01001024/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1025private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001026 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001027 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1028
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001029 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001030 f_gmm_auth();
1031 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001032 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001033
Harald Welte955aa942019-05-03 01:29:29 +02001034 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1035 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001036 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001037 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001038 setverdict(pass);
1039}
Harald Welte3823e2e2018-02-16 21:53:48 +01001040testcase TC_attach_combined() runs on test_CT {
1041 var BSSGP_ConnHdlr vc_conn;
1042 f_init();
1043 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001044 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001045 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001046 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001047}
1048
Harald Welte76dee092018-02-16 22:12:59 +01001049/* Attempt of GPRS ATTACH in 'accept all' mode */
1050private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001051 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001052 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1053
1054 g_pars.net.expect_auth := false;
1055
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001056 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001057 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001058 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1059 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001060 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001061 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001062 setverdict(pass);
1063}
1064testcase TC_attach_accept_all() runs on test_CT {
1065 var BSSGP_ConnHdlr vc_conn;
1066 f_init();
1067 f_sleep(1.0);
1068 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001069 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001070 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001071 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001072}
Harald Welte5b7c8122018-02-16 21:48:17 +01001073
Harald Welteb2124b22018-02-16 22:26:56 +01001074/* Attempt of GPRS ATTACH in 'accept all' mode */
1075private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001076 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1077
1078 /* Simulate a foreign IMSI */
1079 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001080 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001081
1082 g_pars.net.expect_auth := false;
1083
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001084 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001085 alt {
1086 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001087 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001088 setverdict(pass);
1089 }
Harald Welte955aa942019-05-03 01:29:29 +02001090 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001091 setverdict(pass);
1092 }
Harald Welte955aa942019-05-03 01:29:29 +02001093 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001094 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001095 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001096 }
Harald Welteb2124b22018-02-16 22:26:56 +01001097 }
1098}
1099testcase TC_attach_closed() runs on test_CT {
1100 var BSSGP_ConnHdlr vc_conn;
1101 f_init();
1102 f_sleep(1.0);
1103 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1104 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001105 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001106 vc_conn.done;
1107 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001108 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001109 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001110 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001111}
1112
Harald Welte04683d02018-02-16 22:43:45 +01001113/* Routing Area Update from Unknown TLLI -> REJECT */
1114private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001115 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1116
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001117 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 +01001118 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001119 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001120 setverdict(pass);
1121 }
1122 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001123 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001124 }
1125}
1126testcase TC_rau_unknown() runs on test_CT {
1127 var BSSGP_ConnHdlr vc_conn;
1128 f_init();
1129 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001130 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001131 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001132 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001133}
1134
Harald Welte91636de2018-02-17 10:16:14 +01001135private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001136 /* first perform regular attach */
1137 f_TC_attach(id);
1138
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001139 f_routing_area_update(g_pars.ra);
1140
Harald Welte91636de2018-02-17 10:16:14 +01001141}
1142testcase TC_attach_rau() runs on test_CT {
1143 var BSSGP_ConnHdlr vc_conn;
1144 f_init();
1145 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001146 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001147 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001148 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001149}
Harald Welte04683d02018-02-16 22:43:45 +01001150
Harald Welte6abb9fe2018-02-17 15:24:48 +01001151/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001152function 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 +02001153 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001154 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001155 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001156 if (expect_purge) {
1157 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1158 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1159 }
1160 T.start;
1161 alt {
1162 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1163 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001164 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001165 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001166 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001167 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001168 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001169 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001170 /* TODO: check if any PDP contexts are deactivated on network side? */
1171 }
1172 [power_off] T.timeout {
1173 setverdict(pass);
1174 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001175 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001176 g_pars.ra := omit;
1177 setverdict(pass);
1178 /* TODO: check if any PDP contexts are deactivated on network side? */
1179 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001180 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001181 if (power_off) {
1182 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1183 } else {
1184 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1185 }
1186 mtc.stop;
1187 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001188 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001189 }
1190}
1191
1192/* IMSI DETACH (non-power-off) for unknown TLLI */
1193private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1194 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1195}
1196testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1197 var BSSGP_ConnHdlr vc_conn;
1198 f_init();
1199 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001200 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001201 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001202 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001203}
1204
1205/* IMSI DETACH (power-off) for unknown TLLI */
1206private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1207 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1208}
1209testcase TC_detach_unknown_poweroff() runs on test_CT {
1210 var BSSGP_ConnHdlr vc_conn;
1211 f_init();
1212 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001213 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001214 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001215 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001216}
1217
1218/* IMSI DETACH (non-power-off) for known TLLI */
1219private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1220 /* first perform regular attach */
1221 f_TC_attach(id);
1222
1223 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1224}
1225testcase TC_detach_nopoweroff() runs on test_CT {
1226 var BSSGP_ConnHdlr vc_conn;
1227 f_init();
1228 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001229 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001230 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001231 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001232}
1233
1234/* IMSI DETACH (power-off) for known TLLI */
1235private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1236 /* first perform regular attach */
1237 f_TC_attach(id);
1238
1239 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1240}
1241testcase TC_detach_poweroff() runs on test_CT {
1242 var BSSGP_ConnHdlr vc_conn;
1243 f_init();
1244 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001245 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001246 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001247 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001248}
1249
Harald Welteeded9ad2018-02-17 20:57:34 +01001250type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001251 BIT3 tid, /* L3 Transaction ID */
1252 BIT4 nsapi, /* SNDCP NSAPI */
1253 BIT4 sapi, /* LLC SAPI */
1254 QoSV qos, /* QoS parameters */
1255 PDPAddressV addr, /* IP address */
1256 octetstring apn optional, /* APN name */
1257 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1258 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001259 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001260 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001261
Harald Welte822f9102018-02-18 20:39:06 +01001262 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1263 OCT4 ggsn_tei_u, /* GGSN TEI User */
1264 octetstring ggsn_ip_c, /* GGSN IP Control */
1265 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001266 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001267
Harald Welte822f9102018-02-18 20:39:06 +01001268 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1269 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1270 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1271 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001272};
1273
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001274
1275private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1276 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1277 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1278 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1279 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1280 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1281 f_gtp_register_teid(apars.ggsn_tei_c);
1282 f_gtp_register_teid(apars.ggsn_tei_u);
1283}
1284
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001285function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001286runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001287 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1288 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001289 var template Recovery_gtpc recovery := omit;
1290
1291 if (send_recovery) {
1292 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1293 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001294
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001295 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 +02001296 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001297 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1298 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1299 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1300 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1301 apars.sgsn_tei_c, apars.gtp_resp_cause,
1302 apars.ggsn_tei_c, apars.ggsn_tei_u,
1303 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001304 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1305 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001306 }
1307 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001308 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001309 setverdict(pass);
1310 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001311 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001312 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001313 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001314 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001315 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001316 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001317 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001318 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001319 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001320 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1321 mtc.stop;
1322 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001323 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001324 setverdict(pass);
1325 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001326 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001327 }
1328}
1329
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001330function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001331runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001332 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1333 var Gtp1cUnitdata g_ud;
1334
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001335 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001336 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1337 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001338 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001339 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1340 }
1341 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001342 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001343 setverdict(pass);
1344 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001345 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001346 }
1347}
1348
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001349function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001350runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001351 var Gtp1cUnitdata g_ud;
1352 var integer seq_nr := 23;
1353 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1354
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001355 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001356 if (error_ind) {
1357 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1358 } else {
1359 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1360 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001361
1362 timer T := 5.0;
1363 T.start;
1364
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001365 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001366 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1367 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001368 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001369 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1370 repeat;
1371 }
1372 [] T.timeout {
1373 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1374 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001375 }
1376}
1377
Harald Welte6f203162018-02-18 22:04:55 +01001378
Harald Welteeded9ad2018-02-17 20:57:34 +01001379/* Table 10.5.156/3GPP TS 24.008 */
1380template (value) QoSV t_QosDefault := {
1381 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1382 delayClass := '100'B, /* best effort */
1383 spare1 := '00'B,
1384 precedenceClass := '010'B, /* normal */
1385 spare2 := '0'B,
1386 peakThroughput := '0000'B, /* subscribed */
1387 meanThroughput := '00000'B, /* subscribed */
1388 spare3 := '000'B,
1389 deliverErroneusSDU := omit,
1390 deliveryOrder := omit,
1391 trafficClass := omit,
1392 maxSDUSize := omit,
1393 maxBitrateUplink := omit,
1394 maxBitrateDownlink := omit,
1395 sduErrorRatio := omit,
1396 residualBER := omit,
1397 trafficHandlingPriority := omit,
1398 transferDelay := omit,
1399 guaranteedBitRateUplink := omit,
1400 guaranteedBitRateDownlink := omit,
1401 sourceStatisticsDescriptor := omit,
1402 signallingIndication := omit,
1403 spare4 := omit,
1404 maxBitrateDownlinkExt := omit,
1405 guaranteedBitRateDownlinkExt := omit,
1406 maxBitrateUplinkExt := omit,
1407 guaranteedBitRateUplinkExt := omit,
1408 maxBitrateDownlinkExt2 := omit,
1409 guaranteedBitRateDownlinkExt2 := omit,
1410 maxBitrateUplinkExt2 := omit,
1411 guaranteedBitRateUplinkExt2 := omit
1412}
1413
1414/* 10.5.6.4 / 3GPP TS 24.008 */
1415template (value) PDPAddressV t_AddrIPv4dyn := {
1416 pdpTypeOrg := '0001'B, /* IETF */
1417 spare := '0000'B,
1418 pdpTypeNum := '21'O, /* IPv4 */
1419 addressInfo := omit
1420}
1421template (value) PDPAddressV t_AddrIPv6dyn := {
1422 pdpTypeOrg := '0001'B, /* IETF */
1423 spare := '0000'B,
1424 pdpTypeNum := '53'O, /* IPv6 */
1425 addressInfo := omit
1426}
1427
Harald Welte37692d82018-02-18 15:21:34 +01001428template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001429 tid := '000'B,
1430 nsapi := '0101'B, /* < 5 are reserved */
1431 sapi := '0011'B, /* 3/5/9/11 */
1432 qos := t_QosDefault,
1433 addr := t_AddrIPv4dyn,
1434 apn := omit,
1435 pco := omit,
1436 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001437 gtp_resp_cause := int2oct(128, 1),
1438 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001439
1440 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001441 ggsn_tei_c := f_rnd_octstring(4),
1442 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001443 ggsn_ip_c := f_inet_addr(ggsn_ip),
1444 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001445 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001446
Harald Welteeded9ad2018-02-17 20:57:34 +01001447 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001448 sgsn_tei_u := omit,
1449 sgsn_ip_c := omit,
1450 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001451}
1452
Harald Welte37692d82018-02-18 15:21:34 +01001453template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1454 connId := 1,
1455 remName := f_inet_ntoa(ip),
1456 remPort := GTP1U_PORT
1457}
1458
1459template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1460 connId := 1,
1461 remName := f_inet_ntoa(ip),
1462 remPort := GTP1C_PORT
1463}
1464
1465private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1466 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1467 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1468}
1469
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001470private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1471 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001472 repeat;
1473 }
1474}
1475
1476template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1477 pDU_SN_UNITDATA := {
1478 nsapi := nsapi,
1479 moreBit := ?,
1480 snPduType := '1'B,
1481 firstSegmentIndicator := ?,
1482 spareBit := ?,
1483 pcomp := ?,
1484 dcomp := ?,
1485 npduNumber := ?,
1486 segmentNumber := ?,
1487 npduNumberContinued := ?,
1488 dataSegmentSnUnitdataPdu := payload
1489 }
1490}
1491
1492/* simple case: single segment, no compression */
1493template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1494 pDU_SN_UNITDATA := {
1495 nsapi := nsapi,
1496 moreBit := '0'B,
1497 snPduType := '1'B,
1498 firstSegmentIndicator := '1'B,
1499 spareBit := '0'B,
1500 pcomp := '0000'B,
1501 dcomp := '0000'B,
1502 npduNumber := '0000'B,
1503 segmentNumber := '0000'B,
1504 npduNumberContinued := '00'O,
1505 dataSegmentSnUnitdataPdu := payload
1506 }
1507}
1508
1509/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001510private 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 +02001511runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001512 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001513 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1514 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001515 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001516 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1517 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001518 [] as_xid(apars, ran_index);
1519 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001520 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1521 [expect_fwd] T.timeout {
1522 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1523 mtc.stop;
1524 }
1525 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1526 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1527 mtc.stop;
1528 }
1529 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001530 }
1531}
1532
Harald Welte64d6b512020-06-17 16:42:00 +02001533/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001534private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001535runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001536 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1537 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1538 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001539 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001540 /* Expect PDU via GTP from SGSN on simulated GGSN */
1541 alt {
1542 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1543 }
1544}
1545
Harald Welteeded9ad2018-02-17 20:57:34 +01001546private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001547 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001548
1549 /* first perform regular attach */
1550 f_TC_attach(id);
1551
1552 f_pdp_ctx_act(apars);
1553}
1554testcase TC_attach_pdp_act() runs on test_CT {
1555 var BSSGP_ConnHdlr vc_conn;
1556 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001557 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001558 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001559 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001560}
Harald Welteb2124b22018-02-16 22:26:56 +01001561
Harald Welte835b15f2018-02-18 14:39:11 +01001562/* PDP Context activation for not-attached subscriber; expect fail */
1563private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001564 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001565 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 +01001566 apars.apn, apars.pco));
1567 alt {
1568 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001569 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001570 setverdict(pass);
1571 }
1572 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1573 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001574 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001575 }
Harald Welte955aa942019-05-03 01:29:29 +02001576 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001577 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001578 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001579 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001580 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001581 }
1582}
1583testcase TC_pdp_act_unattached() runs on test_CT {
1584 var BSSGP_ConnHdlr vc_conn;
1585 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001586 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001587 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001588 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001589}
1590
Harald Welte37692d82018-02-18 15:21:34 +01001591/* ATTACH + PDP CTX ACT + user plane traffic */
1592private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1593 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1594
1595 /* first perform regular attach */
1596 f_TC_attach(id);
1597 /* then activate PDP context */
1598 f_pdp_ctx_act(apars);
1599 /* then transceive a downlink PDU */
1600 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1601 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1602}
1603testcase TC_attach_pdp_act_user() runs on test_CT {
1604 var BSSGP_ConnHdlr vc_conn;
1605 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001606 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001607 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001608 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001609}
1610
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001611/* ATTACH + PDP CTX ACT; reject from GGSN */
1612private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1613 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1614
1615 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1616 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1617
1618 /* first perform regular attach */
1619 f_TC_attach(id);
1620 /* then activate PDP context */
1621 f_pdp_ctx_act(apars);
1622}
1623testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1624 var BSSGP_ConnHdlr vc_conn;
1625 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001626 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001627 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001628 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001629}
Harald Welte835b15f2018-02-18 14:39:11 +01001630
Harald Welte6f203162018-02-18 22:04:55 +01001631/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1632private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1633 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1634
1635 /* first perform regular attach */
1636 f_TC_attach(id);
1637 /* then activate PDP context */
1638 f_pdp_ctx_act(apars);
1639 /* then transceive a downlink PDU */
1640 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1641 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1642
1643 f_pdp_ctx_deact_mo(apars, '00'O);
1644}
1645testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1646 var BSSGP_ConnHdlr vc_conn;
1647 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001648 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb, 21);
Harald Welte6f203162018-02-18 22:04:55 +01001649 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001650 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001651}
1652
Harald Welte57b9b7f2018-02-18 22:28:13 +01001653/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1654private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1655 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1656
1657 /* first perform regular attach */
1658 f_TC_attach(id);
1659 /* then activate PDP context */
1660 f_pdp_ctx_act(apars);
1661 /* then transceive a downlink PDU */
1662 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1663 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1664
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001665 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001666}
1667testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1668 var BSSGP_ConnHdlr vc_conn;
1669 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001670 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 +01001671 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001672 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001673}
1674
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001675/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1676private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1677 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1678 var Gtp1cUnitdata g_ud;
1679 var integer i;
1680 var OCT1 cause_regular_deact := '24'O;
1681
1682 /* first perform regular attach + PDP context act */
1683 f_TC_attach(id);
1684 f_pdp_ctx_act(apars);
1685
1686 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1687 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1688
1689 for (i := 0; i < 2; i := i+1) {
1690 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1691 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1692 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1693 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1694 }
1695 }
1696
1697 alt {
1698 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1699 setverdict(pass);
1700 }
1701 [] as_xid(apars, 0);
1702 }
1703
1704 /* Make sure second DeactPdpAccept is sent: */
1705 timer T := 2.0;
1706 T.start;
1707 alt {
1708 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1709 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1710 }
1711 [] T.timeout {
1712 setverdict(pass);
1713 }
1714 }
1715
1716 setverdict(pass);
1717}
1718testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1719 var BSSGP_ConnHdlr vc_conn;
1720 f_init();
1721 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1722 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001723 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001724}
1725
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001726/* ATTACH + ATTACH (2nd) */
1727private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1728 g_pars.t_guard := 5.0;
1729
1730 /* first perform regular attach */
1731 f_TC_attach(id);
1732
1733 /* second to perform regular attach */
1734 f_TC_attach(id);
1735}
1736
1737
1738testcase TC_attach_second_attempt() runs on test_CT {
1739 var BSSGP_ConnHdlr vc_conn;
1740 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001741 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001742 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001743 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001744}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001745
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001746private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1747 var Gtp1cUnitdata g_ud;
1748 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1749 var integer seq_nr;
1750
1751 /* first perform regular attach */
1752 f_TC_attach(id);
1753 /* then activate PDP context */
1754 f_pdp_ctx_act(apars);
1755
1756 /* Wait to receive first echo request and send initial Restart counter */
1757 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1758 BSSGP[0].clear;
1759 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1760 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1761 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1762 }
1763
1764 /* At some point next echo request not answered will timeout and SGSN
1765 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1766 timer T := 3.0 * 6.0 + 16.0;
1767 T.start;
1768 alt {
1769 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1770 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1771 setverdict(pass);
1772 }
1773 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1774 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1775 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1776 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1777 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1778 repeat;
1779 }
1780 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1781 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1782 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1783 repeat;
1784 }
1785 [] T.timeout {
1786 setverdict(fail, "BSSGP DeactPdpReq not received");
1787 mtc.stop;
1788 }
1789 [] as_xid(apars);
1790 }
1791 T.stop
1792
1793 setverdict(pass);
1794}
1795/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1796testcase TC_attach_echo_timeout() runs on test_CT {
1797 var BSSGP_ConnHdlr vc_conn;
1798 g_use_echo := true;
1799 f_init();
1800 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1801 vc_conn.done;
1802 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001803 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001804}
1805
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001806private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001807 var Gtp1cUnitdata g_ud;
1808 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1809
1810 /* first perform regular attach */
1811 f_TC_attach(id);
1812 /* Activate a pdp context against the GGSN */
1813 f_pdp_ctx_act(apars);
1814 /* Wait to receive first echo request and send initial Restart counter */
1815 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1816 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1817 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1818 }
1819 /* Wait to receive second echo request and send incremented Restart
1820 counter. This will fake a restarted GGSN, and pdp ctx allocated
1821 should be released by SGSN */
1822 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1823 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1824 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1825 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1826 }
1827 var OCT1 cause_network_failure := int2oct(38, 1)
1828 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001829 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001830 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001831 setverdict(pass);
1832 }
1833 [] as_xid(apars);
1834 }
1835 setverdict(pass);
1836}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001837/* ATTACH + trigger Recovery procedure through EchoResp */
1838testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001839 var BSSGP_ConnHdlr vc_conn;
1840 g_use_echo := true
1841 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001842 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 +02001843 vc_conn.done;
1844 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001845 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001846}
1847
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001848private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1849 var Gtp1cUnitdata g_ud;
1850 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1851 var integer seq_nr := 23;
1852 var GtpPeer peer;
1853 /* first perform regular attach */
1854 f_TC_attach(id);
1855
1856 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1857 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1858 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1859 f_pdp_ctx_act(apars, true);
1860
1861 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1862/* received. */
1863 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1864
1865 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1866 would be great to have an active pdp context here before triggering
1867 Recovery, and making sure the the DEACT request is sent by the SGSN.
1868 */
1869
1870 /* Activate a pdp context against the GGSN, send incremented Recovery
1871 IE. This should trigger the recovery path, but still this specific
1872 CTX activation should work. */
1873 apars.exp_rej_cause := omit; /* default value for tests */
1874 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1875 f_pdp_ctx_act(apars, true);
1876
1877 setverdict(pass);
1878}
1879/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1880testcase TC_attach_restart_ctr_create() runs on test_CT {
1881 var BSSGP_ConnHdlr vc_conn;
1882 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001883 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 +02001884 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001885 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001886}
1887
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001888/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1889private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1890 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1891 var integer seq_nr := 23;
1892 var GtpPeer peer;
1893 var integer i;
1894
1895 /* first perform regular attach */
1896 f_TC_attach(id);
1897 /* then activate PDP context */
1898 f_pdp_ctx_act(apars);
1899
Alexander Couzens0e510e62018-07-28 23:06:00 +02001900 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001901 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1902 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1903
1904 for (i := 0; i < 5; i := i+1) {
1905 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001906 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001907 [] as_xid(apars);
1908 }
1909 }
1910
1911 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1912
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001913 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001914 setverdict(pass);
1915}
1916testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1917 var BSSGP_ConnHdlr vc_conn;
1918 f_init();
1919 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001920 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 +02001921 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001922 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001923}
1924
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001925/* ATTACH + PDP CTX ACT dropped + retrans */
1926private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1927 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1928 var Gtp1cUnitdata g_ud_first, g_ud_second;
1929 /* first perform regular attach */
1930 f_TC_attach(id);
1931
1932 /* then activate PDP context on the Gb side */
1933 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1934 apars.apn, apars.pco), 0);
1935
1936 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1937 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1938 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1939 if (g_ud_first != g_ud_second) {
1940 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1941 mtc.stop;
1942 }
1943 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1944 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1945 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1946 apars.sgsn_tei_c, apars.gtp_resp_cause,
1947 apars.ggsn_tei_c, apars.ggsn_tei_u,
1948 apars.nsapi,
1949 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1950 omit, omit));
1951 }
Harald Welte955aa942019-05-03 01:29:29 +02001952 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001953
1954 /* Now the same with Deact */
1955 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1956 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1957 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1958 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1959 if (g_ud_first != g_ud_second) {
1960 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1961 mtc.stop;
1962 }
1963 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1964 BSSGP[0].clear;
1965 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1966 }
1967 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001968 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001969 setverdict(pass);
1970 }
1971 [] as_xid(apars, 0);
1972 }
1973
1974 setverdict(pass);
1975}
1976testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1977 var BSSGP_ConnHdlr vc_conn;
1978 f_init();
1979 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1980 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001981 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001982}
1983
1984/* Test that SGSN GTP response retransmit queue works fine */
1985private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1986 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1987 var integer seq_nr := 23;
1988 var Gtp1cUnitdata g_ud_first, g_ud_second;
1989 var template Gtp1cUnitdata g_delete_req;
1990 /* first perform regular attach + PDP context act */
1991 f_TC_attach(id);
1992 f_pdp_ctx_act(apars);
1993
1994 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1995 BSSGP[0].clear;
1996 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1997 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1998 GTP.send(g_delete_req);
1999 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002000 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002001 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2002 }
2003 [] as_xid(apars, 0);
2004 }
2005 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2006 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2007 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2008 mtc.stop;
2009 }
2010 };
2011
2012 /* Send duplicate DeleteCtxReq */
2013 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2014 GTP.send(g_delete_req);
2015 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2016 if (g_ud_first != g_ud_second) {
2017 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2018 mtc.stop;
2019 }
2020 }
2021
2022 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2023 * is handled differently by SGSN (expect "non-existent" cause) */
2024 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2025 GTP.send(g_delete_req);
2026 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2027 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2028 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2029 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2030 mtc.stop;
2031 }
2032 }
2033
2034 setverdict(pass);
2035}
2036testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2037 var BSSGP_ConnHdlr vc_conn;
2038 f_init();
2039 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2040 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002041 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002042}
2043
Alexander Couzens5e307b42018-05-22 18:12:20 +02002044private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2045 /* MS: perform regular attach */
2046 f_TC_attach(id);
2047
2048 /* HLR: cancel the location request */
2049 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2050 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002051
2052 /* ensure no Detach Request got received */
2053 timer T := 5.0;
2054 T.start;
2055 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002056 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002057 T.stop;
2058 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002059 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002060 }
2061 [] T.timeout {
2062 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002063 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002064 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002065 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002066 repeat;
2067 }
2068 }
2069}
2070
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002071/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2072private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2073 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2074
2075 /* first perform regular attach */
2076 f_TC_attach(id);
2077 /* then activate PDP context */
2078 f_pdp_ctx_act(apars);
2079 /* then transceive a downlink PDU */
2080 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2081
2082 /* Send Error indication as response from upload PDU and expect deact towards MS */
2083 f_pdp_ctx_deact_mt(apars, true);
2084}
2085testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2086 var BSSGP_ConnHdlr vc_conn;
2087 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002088 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 +02002089 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002090 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002091}
2092
Alexander Couzens5e307b42018-05-22 18:12:20 +02002093testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2094 /* MS <-> SGSN: GMM Attach
2095 * HLR -> SGSN: Cancel Location Request
2096 * HLR <- SGSN: Cancel Location Ack
2097 */
2098 var BSSGP_ConnHdlr vc_conn;
2099 f_init();
2100 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002101 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002102 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002103 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002104}
2105
2106
Alexander Couzensc87967a2018-05-22 16:09:54 +02002107private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2108 /* MS: perform regular attach */
2109 f_TC_attach(id);
2110
2111 /* HLR: cancel the location request */
2112 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2113 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2114 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2115
2116 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002117 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002118 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002119
2120 setverdict(pass);
2121}
2122
2123testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2124 /* MS <-> SGSN: GMM Attach
2125 * HLR -> SGSN: Cancel Location Request
2126 * HLR <- SGSN: Cancel Location Ack
2127 * MS <- SGSN: Detach Request
2128 * SGSN-> MS: Detach Complete
2129 */
2130 var BSSGP_ConnHdlr vc_conn;
2131 f_init();
2132 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002133 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002134 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002135 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002136}
2137
2138
Alexander Couzens6c47f292018-05-22 17:09:49 +02002139private function f_hlr_location_cancel_request_unknown_subscriber(
2140 charstring id,
2141 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2142
2143 /* HLR: cancel the location request */
2144 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2145
2146 /* cause 2 = IMSI_UNKNOWN */
2147 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2148
2149 setverdict(pass);
2150}
2151
2152private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002153 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002154}
2155
2156testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2157 /* HLR -> SGSN: Cancel Location Request
2158 * HLR <- SGSN: Cancel Location Error
2159 */
2160
2161 var BSSGP_ConnHdlr vc_conn;
2162 f_init();
2163 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002164 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 +02002165 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002166 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002167}
2168
2169private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002170 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002171}
2172
2173testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2174 /* HLR -> SGSN: Cancel Location Request
2175 * HLR <- SGSN: Cancel Location Error
2176 */
2177
2178 var BSSGP_ConnHdlr vc_conn;
2179 f_init();
2180 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002181 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 +02002182 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002183 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002184}
2185
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002186private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2187 f_TC_attach(id);
2188 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2189}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002190
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002191testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2192 /* MS <-> SGSN: Attach
2193 * MS -> SGSN: Detach Req (Power off)
2194 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2195 */
2196 var BSSGP_ConnHdlr vc_conn;
2197 var integer id := 33;
2198 var charstring imsi := hex2str(f_gen_imsi(id));
2199
2200 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002201 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002202 vc_conn.done;
2203
2204 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002205 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002206}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002207
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002208/* Attempt an attach, but loose the Identification Request (IMEI) */
2209private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2210 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002211 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002212
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002213 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 +02002214
2215 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002216 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002217 /* break */
2218 }
Harald Welte955aa942019-05-03 01:29:29 +02002219 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002220 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002221 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002222 repeat;
2223 }
Harald Welte955aa942019-05-03 01:29:29 +02002224 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002225 /* ignore ID REQ IMEI */
2226 count_req := count_req + 1;
2227 repeat;
2228 }
2229 }
2230 if (count_req != 5) {
2231 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002232 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002233 }
2234 setverdict(pass);
2235}
2236
2237testcase TC_attach_no_imei_response() runs on test_CT {
2238 /* MS -> SGSN: Attach Request IMSI
2239 * MS <- SGSN: Identity Request IMSI (optional)
2240 * MS -> SGSN: Identity Response IMSI (optional)
2241 * MS <- SGSN: Identity Request IMEI
2242 * MS -x SGSN: no response
2243 * MS <- SGSN: re-send: Identity Request IMEI 4x
2244 * MS <- SGSN: Attach Reject
2245 */
2246 var BSSGP_ConnHdlr vc_conn;
2247 f_init();
2248 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002249 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 +02002250 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002251 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002252}
2253
Alexander Couzens53f20562018-06-12 16:24:12 +02002254/* Attempt an attach, but loose the Identification Request (IMSI) */
2255private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2256 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002257 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002258
2259 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2260 g_pars.p_tmsi := 'c0000035'O;
2261
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002262 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 +02002263
2264 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002265 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002266 /* break */
2267 }
Harald Welte955aa942019-05-03 01:29:29 +02002268 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002269 /* ignore ID REQ IMSI */
2270 count_req := count_req + 1;
2271 repeat;
2272 }
Harald Welte955aa942019-05-03 01:29:29 +02002273 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002274 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002275 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002276 repeat;
2277 }
2278 }
2279 if (count_req != 5) {
2280 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002281 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002282 }
2283 setverdict(pass);
2284}
2285
2286testcase TC_attach_no_imsi_response() runs on test_CT {
2287 /* MS -> SGSN: Attach Request TMSI (unknown)
2288 * MS <- SGSN: Identity Request IMEI (optional)
2289 * MS -> SGSN: Identity Response IMEI (optional)
2290 * MS <- SGSN: Identity Request IMSI
2291 * MS -x SGSN: no response
2292 * MS <- SGSN: re-send: Identity Request IMSI 4x
2293 * MS <- SGSN: Attach Reject
2294 */
2295 var BSSGP_ConnHdlr vc_conn;
2296 f_init();
2297 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002298 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 +02002299 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002300 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002301}
2302
Alexander Couzenscf818962018-06-05 18:00:00 +02002303private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2304 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2305}
2306
2307testcase TC_attach_check_subscriber_list() runs on test_CT {
2308 /* MS <-> SGSN: Attach
2309 * VTY -> SGSN: Check if MS is in subscriber cache
2310 */
2311 var BSSGP_ConnHdlr vc_conn;
2312 var integer id := 34;
2313 var charstring imsi := hex2str(f_gen_imsi(id));
2314
2315 f_init();
2316 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002317 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002318 vc_conn.done;
2319
2320 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2321 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002322 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002323}
2324
Alexander Couzensf9858652018-06-07 16:14:53 +02002325private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2326 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002327 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002328
2329 /* unregister the old IMSI */
2330 f_bssgp_client_unregister(g_pars.imsi);
2331 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002332 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002333 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002334
2335 /* there is no auth */
2336 g_pars.net.expect_auth := false;
2337
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002338 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002339 f_gmm_auth();
2340 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002341 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002342 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002343 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002344 }
Harald Welte955aa942019-05-03 01:29:29 +02002345 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2346 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002347 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002348 setverdict(pass);
2349 }
2350 }
2351}
Alexander Couzens03d12242018-08-07 16:13:52 +02002352
2353private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2354
2355 f_TC_attach_closed_foreign(id);
2356 f_TC_attach_closed_imsi_added(id);
2357
2358}
2359
2360
Alexander Couzensf9858652018-06-07 16:14:53 +02002361testcase TC_attach_closed_add_vty() runs on test_CT {
2362 /* VTY-> SGSN: policy close
2363 * MS -> SGSN: Attach Request
2364 * MS <- SGSN: Identity Request IMSI
2365 * MS -> SGSN: Identity Response IMSI
2366 * MS <- SGSN: Attach Reject
2367 * VTY-> SGSN: policy imsi-acl add IMSI
2368 * MS -> SGSN: Attach Request
2369 * MS <- SGSN: Identity Request IMSI
2370 * MS -> SGSN: Identity Response IMSI
2371 * MS <- SGSN: Identity Request IMEI
2372 * MS -> SGSN: Identity Response IMEI
2373 * MS <- SGSN: Attach Accept
2374 */
2375 var BSSGP_ConnHdlr vc_conn;
2376 f_init();
2377 f_sleep(1.0);
2378 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2379 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002380 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2381 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002382 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002383 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002384 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002385 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002386}
2387
Alexander Couzens0085bd72018-06-12 19:08:44 +02002388/* Attempt an attach, but never answer a Attach Complete */
2389private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2390 var integer count_req := 0;
2391
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002392 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 +02002393 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002394 /* Expect SGSN to perform LU with HLR */
2395 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002396
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002397 timer T := 10.0;
2398 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002399 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002400 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002401 /* break */
2402 }
Harald Welte955aa942019-05-03 01:29:29 +02002403 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002404 /* ignore */
2405 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002406 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002407 repeat;
2408 }
2409 }
2410 if (count_req != 5) {
2411 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002412 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002413 }
2414 setverdict(pass);
2415}
2416
2417testcase TC_attach_check_complete_resend() runs on test_CT {
2418 /* MS -> SGSN: Attach Request IMSI
2419 * MS <- SGSN: Identity Request *
2420 * MS -> SGSN: Identity Response *
2421 * MS <- SGSN: Attach Complete 5x
2422 */
2423 var BSSGP_ConnHdlr vc_conn;
2424 f_init();
2425 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002426 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 +02002427 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002428 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002429}
2430
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002431friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002432 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002433 var PDU_DTAP_PS_MT mt;
2434 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002435
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002436 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002437 p_tmsi := g_pars.p_tmsi;
2438 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002439 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002440 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit, p_tmsi), ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002441 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002442 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2443 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2444 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002445 setverdict(pass);
2446 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002447 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2448 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2449 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002450 setverdict(pass);
2451 }
2452
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002453 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002454 setverdict(fail, "Unexpected RAU Reject");
2455 mtc.stop;
2456 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002457 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002458 setverdict(fail, "Unexpected RAU Reject");
2459 mtc.stop;
2460 }
2461
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002462 [is_iu(ran_index)] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
Alexander Couzens5d56f522019-09-03 12:36:18 +02002463 key_sts := ?)) {
2464 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2465 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002466 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002467 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002468 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002469 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2470 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002471 }
2472}
2473
Alexander Couzensbfda9212018-07-31 03:17:33 +02002474private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002475 /* first perform regular attach */
2476 f_TC_attach(id);
2477
2478 /* then send RAU */
2479 f_routing_area_update(g_pars.ra);
2480
2481 /* do another RAU */
2482 f_routing_area_update(g_pars.ra);
2483
2484 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2485}
2486
2487testcase TC_attach_rau_a_a() runs on test_CT {
2488 /* MS <-> SGSN: Successful Attach
2489 * MS -> SGSN: Routing Area Update Request
2490 * MS <- SGSN: Routing Area Update Accept
2491 * MS -> SGSN: Routing Area Update Request
2492 * MS <- SGSN: Routing Area Update Accept
2493 * MS -> SGSN: Detach (PowerOff)
2494 */
2495 var BSSGP_ConnHdlr vc_conn;
2496 f_init();
2497 f_sleep(1.0);
2498 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2499 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002500 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002501}
2502
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002503private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002504 f_TC_attach(id);
2505
2506 log("attach complete sending rau");
2507 f_routing_area_update(g_pars.ra, 0);
2508
2509 log("rau complete unregistering");
2510 f_bssgp_client_unregister(g_pars.imsi);
2511 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2512
2513 log("sending second RAU via different RA");
2514 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2515
2516 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2517}
2518
2519testcase TC_attach_rau_a_b() runs on test_CT {
2520 /* MS <-> SGSN: Successful Attach
2521 * MS -> SGSN: Routing Area _a_ Update Request
2522 * MS <- SGSN: Routing Area _a_ Update Accept
2523 * MS -> SGSN: Routing Area _b_ Update Request
2524 * MS <- SGSN: Routing Area _b_ Update Accept
2525 * MS -> SGSN: Detach (PowerOff)
2526 */
2527 var BSSGP_ConnHdlr vc_conn;
2528 f_init();
2529 f_sleep(1.0);
2530 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2531 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002532 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002533}
2534
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002535private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2536 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002537 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002538 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002539 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002540
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002541 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002542
2543 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002544 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002545 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2546 mtc.stop;
2547 }
Harald Welte955aa942019-05-03 01:29:29 +02002548 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002549 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002550 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002551 repeat;
2552 }
Harald Welte955aa942019-05-03 01:29:29 +02002553 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002554 /* send out a second GMM_Attach Request.
2555 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2556 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002557 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002558 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002559 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002560 }
2561 }
2562 f_sleep(1.0);
2563
2564 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2565 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002566 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002567 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002568 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002569 repeat;
2570 }
Harald Welte955aa942019-05-03 01:29:29 +02002571 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002572 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2573 mtc.stop;
2574 }
Harald Welte955aa942019-05-03 01:29:29 +02002575 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002576 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2577 mtc.stop;
2578 }
Harald Welte955aa942019-05-03 01:29:29 +02002579 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2580 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002581 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002582 setverdict(pass);
2583 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2584 }
2585 }
2586}
2587
2588testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2589 /* Testing if the SGSN ignore Attach Request with the exact same content */
2590 /* MS -> SGSN: Attach Request IMSI
2591 * MS <- SGSN: Identity Request IMSI (optional)
2592 * MS -> SGSN: Identity Response IMSI (optional)
2593 * MS <- SGSN: Identity Request IMEI
2594 * MS -> SGSN: Attach Request (2nd)
2595 * MS <- SGSN: Identity Response IMEI
2596 * MS <- SGSN: Attach Accept
2597 * MS -> SGSN: Attach Complete
2598 */
2599 var BSSGP_ConnHdlr vc_conn;
2600 f_init();
2601 f_sleep(1.0);
2602 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2603 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2604 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002605 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002606}
2607
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002608private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002609 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2610
2611 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2612
2613 /* send Attach Request */
2614 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2615 * 3G auth vectors */
2616 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2617 /* The thing is, if the solSACapability is 'omit', then the
2618 * revisionLevelIndicatior is at the wrong place! */
2619 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002620 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002621
2622 /* do the auth */
2623 var PDU_L3_MS_SGSN l3_mo;
2624 var PDU_L3_SGSN_MS l3_mt;
2625 var default di := activate(as_mm_identity());
2626
2627 var GSUP_IE auth_tuple;
2628 var template AuthenticationParameterAUTNTLV autn;
2629
2630 g_pars.vec := f_gen_auth_vec_3g();
2631 autn := {
2632 elementIdentifier := '28'O,
2633 lengthIndicator := lengthof(g_pars.vec.autn),
2634 autnValue := g_pars.vec.autn
2635 };
2636 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2637 g_pars.vec.sres,
2638 g_pars.vec.kc,
2639 g_pars.vec.ik,
2640 g_pars.vec.ck,
2641 g_pars.vec.autn,
2642 g_pars.vec.res));
2643 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2644 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2645 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2646
2647 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2648 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002649 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002650
2651 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002652 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002653
2654 /* wait for the GSUP resync request */
2655 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2656 g_pars.imsi,
2657 g_pars.vec.auts,
2658 g_pars.vec.rand));
2659
2660 /* generate new key material */
2661 g_pars.vec := f_gen_auth_vec_3g();
2662 autn := {
2663 elementIdentifier := '28'O,
2664 lengthIndicator := lengthof(g_pars.vec.autn),
2665 autnValue := g_pars.vec.autn
2666 };
2667
2668 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2669 g_pars.vec.sres,
2670 g_pars.vec.kc,
2671 g_pars.vec.ik,
2672 g_pars.vec.ck,
2673 g_pars.vec.autn,
2674 g_pars.vec.res));
2675 /* send new key material */
2676 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2677
2678 /* wait for the new Auth Request */
2679 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2680 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002681 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002682 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2683 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2684 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2685 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2686 valueField := substr(g_pars.vec.res, 0, 4)
2687 };
2688 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2689 elementIdentifier := '21'O,
2690 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2691 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2692 };
2693 l3_mo := valueof(auth_ciph_resp);
2694 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2695 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2696 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2697 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2698 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002699 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002700 deactivate(di);
2701
2702 /* Expect SGSN to perform LU with HLR */
2703 f_gmm_gsup_lu_isd();
2704
Harald Welte955aa942019-05-03 01:29:29 +02002705 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2706 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002707 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002708 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002709 setverdict(pass);
2710}
2711
2712testcase TC_attach_usim_resync() runs on test_CT {
2713 /* MS -> SGSN: Attach Request
2714 * MS <- SGSN: Identity Request IMSI
2715 * MS -> SGSN: Identity Response IMSI
2716 * MS <- SGSN: Identity Request IMEI
2717 * MS -> SGSN: Identity Response IMEI
2718 * HLR<- SGSN: SAI Request
2719 * HLR-> SGSN: SAI Response
2720 * MS <- SGSN: Auth Request
2721 * MS -> SGSN: Auth Failure (with AUTS)
2722 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2723 * HLR-> SGSN: SAI Response (new key material)
2724 * MS <- SGSN: Auth Request (new key material)
2725 * MS -> SGSN: Auth Response
2726 * MS <- SGSN: Attach Accept
2727 * MS -> SGSN: Attach Complete
2728 */
2729 var BSSGP_ConnHdlr vc_conn;
2730 f_init();
2731 f_sleep(1.0);
2732 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2733 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002734 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002735}
2736
Harald Weltea05b8072019-04-23 22:35:05 +02002737
2738/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2739private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2740 f_gmm_attach(false, false);
2741 f_sleep(1.0);
2742 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2743 /* try to detach to check if SGSN is still alive */
2744 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2745}
2746testcase TC_llc_null() runs on test_CT {
2747 var BSSGP_ConnHdlr vc_conn;
2748 f_init();
2749 f_sleep(1.0);
2750 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2751 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002752 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002753}
2754
Harald Welte645a1512019-04-23 23:18:23 +02002755/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2756private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2757 f_gmm_attach(false, false);
2758 f_sleep(1.0);
2759 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002760 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002761 setverdict(pass);
2762}
2763testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2764 var BSSGP_ConnHdlr vc_conn;
2765 f_init();
2766 f_sleep(1.0);
2767 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2768 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002769 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002770}
2771
2772/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2773private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2774 f_gmm_attach(false, false);
2775 f_sleep(1.0);
2776 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002777 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002778 setverdict(pass);
2779}
2780testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2781 var BSSGP_ConnHdlr vc_conn;
2782 f_init();
2783 f_sleep(1.0);
2784 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2785 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002786 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002787}
2788
Harald Welte2aaac1b2019-05-02 10:02:53 +02002789/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2790private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2791 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2792 var template (value) XID_Information xid;
2793 var template XID_Information xid_rx;
2794
2795 /* first perform regular attach */
2796 f_TC_attach(id);
2797 /* then activate PDP context */
2798 f_pdp_ctx_act(apars);
2799
2800 /* start MO XID */
2801 xid := { ts_XID_L3(''O) };
2802 xid_rx := { tr_XID_L3(''O) };
2803 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2804 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002805 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002806 [] as_xid(apars);
2807 }
2808 setverdict(pass);
2809}
2810testcase TC_xid_empty_l3() runs on test_CT {
2811 var BSSGP_ConnHdlr vc_conn;
2812 f_init();
2813 f_sleep(1.0);
2814 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2815 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002816 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002817}
2818
2819private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2820 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2821 var template (value) XID_Information xid;
2822 var template XID_Information xid_rx;
2823
2824 /* first perform regular attach */
2825 f_TC_attach(id);
2826 /* then activate PDP context */
2827 f_pdp_ctx_act(apars);
2828
2829 /* start MO XID */
2830 xid := { ts_XID_N201U(1234) };
2831 xid_rx := { tr_XID_N201U(1234) };
2832 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2833 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002834 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002835 [] as_xid(apars);
2836 }
2837 setverdict(pass);
2838}
2839testcase TC_xid_n201u() runs on test_CT {
2840 var BSSGP_ConnHdlr vc_conn;
2841 f_init();
2842 f_sleep(1.0);
2843 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2844 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002845 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002846}
2847
Alexander Couzens6bee0872019-05-11 01:48:50 +02002848private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2849 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2850
2851 /* first perform regular attach */
2852 f_TC_attach(id);
2853 /* then activate PDP context */
2854 f_pdp_ctx_act(apars);
2855 /* do a normal detach */
2856 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2857}
2858
2859testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2860 /* MS -> SGSN: Attach Request
2861 * MS <-> SGSN: [..]
2862 * MS -> SGSN: Attach Complete
2863 * MS -> SGSN: PDP Activate Request
2864 * MS <- SGSN: PDP Activate Accept
2865 * MS -> SGSN: GMM Detach Request
2866 * MS <- SGSN: GMM Detach Accept
2867 */
2868 var BSSGP_ConnHdlr vc_conn;
2869 f_init();
2870 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2871 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002872 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002873}
Harald Welte645a1512019-04-23 23:18:23 +02002874
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002875private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2876 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2877 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2878 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2879 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2880 var PDU_L3_SGSN_MS l3_mt;
2881
2882 f_send_l3(attach_req, 0);
2883
2884 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2885
2886 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2887 alt {
2888 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2889 setverdict(pass);
2890 }
2891 [] BSSGP[0].receive { repeat; }
2892 }
2893}
2894
2895/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2896 * See OS#3957 and OS#4245 for more information.
2897 */
2898testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2899 /*
2900 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2901 * MS <-- SGSN: Identity Request (IMEI)
2902 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2903 */
2904 var BSSGP_ConnHdlr vc_conn;
2905 f_init();
2906 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2907 vc_conn.done;
2908 f_cleanup();
2909}
2910
Harald Welte8e5932e2020-06-17 22:12:54 +02002911private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2912var PDU_BSSGP rx;
2913[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2914 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2915 mtc.stop;
2916 }
2917}
2918
2919/* SUSPEND, then DL traffic: should not pass + no paging expected */
2920private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2921 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2922 var default d;
2923
2924 /* first perform regular attach */
2925 f_TC_attach(id);
2926 /* then activate PDP context */
2927 f_pdp_ctx_act(apars);
2928 /* then transceive a downlink PDU */
2929 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2930
2931 /* now suspend GPRS */
2932 f_bssgp_suspend();
2933
2934 d := activate(as_nopaging_ps());
2935
2936 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2937 * nor any related paging requests */
2938 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2939
2940 deactivate(d);
2941}
2942testcase TC_suspend_nopaging() runs on test_CT {
2943 var BSSGP_ConnHdlr vc_conn;
2944 f_init();
2945 f_sleep(1.0);
2946 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
2947 vc_conn.done;
2948 f_cleanup();
2949}
2950
2951
2952/* SUSPEND, then RESUME: data expected to flow after explicit resume */
2953private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
2954 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2955 var OCT1 susp_ref;
2956 var default d;
2957
2958 /* first perform regular attach */
2959 f_TC_attach(id);
2960 /* then activate PDP context */
2961 f_pdp_ctx_act(apars);
2962 /* then transceive a downlink PDU */
2963 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2964
2965 /* now suspend GPRS */
2966 susp_ref := f_bssgp_suspend();
2967
2968 d := activate(as_nopaging_ps());
2969
2970 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2971 * nor any related paging requests */
2972 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2973
2974 deactivate(d);
2975
2976 /* resume GPRS */
2977 f_bssgp_resume(susp_ref);
2978
2979 /* now data should be flowing again */
2980 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2981}
2982testcase TC_suspend_resume() runs on test_CT {
2983 var BSSGP_ConnHdlr vc_conn;
2984 f_init();
2985 f_sleep(1.0);
2986 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
2987 vc_conn.done;
2988 f_cleanup();
2989}
2990
2991/* SUSPEND, then RAU: data expected to flow after implicit resume */
2992private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
2993 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2994 var default d;
2995
2996 /* first perform regular attach */
2997 f_TC_attach(id);
2998 /* then activate PDP context */
2999 f_pdp_ctx_act(apars);
3000 /* then transceive a downlink PDU */
3001 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3002
3003 /* now suspend GPRS */
3004 f_bssgp_suspend();
3005
3006 d := activate(as_nopaging_ps());
3007
3008 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3009 * nor any related paging requests */
3010 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3011
3012 deactivate(d);
3013
3014 /* perform RAU (implicit RESUME) */
3015 f_routing_area_update(g_pars.ra);
3016
3017 /* now data should be flowing again */
3018 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3019
3020}
3021testcase TC_suspend_rau() runs on test_CT {
3022 var BSSGP_ConnHdlr vc_conn;
3023 f_init();
3024 f_sleep(1.0);
3025 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3026 vc_conn.done;
3027 f_cleanup();
3028}
3029
3030
3031/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3032private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3033 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3034 var default d;
3035
3036 /* first perform regular attach */
3037 f_TC_attach(id);
3038 /* then activate PDP context */
3039 f_pdp_ctx_act(apars);
3040 /* then transceive a downlink PDU */
3041 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3042
3043 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3044 f_sleep(5.0);
3045
3046 /* now data should be flowing again, but with PS PAGING */
3047 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3048 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3049
3050 /* FIXME: simulate paging response */
3051 /* FIXME: verify PDU actually arrives only after paging response was successful */
3052
3053}
3054testcase TC_paging_ps() runs on test_CT {
3055 var BSSGP_ConnHdlr vc_conn;
3056 f_init();
3057 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3058 f_sleep(1.0);
3059 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3060 vc_conn.done;
3061 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3062 f_cleanup();
3063}
3064
3065
3066
3067
3068
Harald Welte5ac31492018-02-15 20:39:13 +01003069control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003070 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003071 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003072 execute( TC_attach_umts_aka_umts_res() );
3073 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003074 execute( TC_attach_auth_id_timeout() );
3075 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003076 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003077 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003078 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003079 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003080 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003081 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003082 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003083 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003084 execute( TC_attach_closed_add_vty(), 20.0 );
3085 execute( TC_attach_check_subscriber_list(), 20.0 );
3086 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003087 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003088 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3089 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3090 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3091 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003092 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003093 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003094 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003095 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003096 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003097 execute( TC_detach_unknown_nopoweroff() );
3098 execute( TC_detach_unknown_poweroff() );
3099 execute( TC_detach_nopoweroff() );
3100 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003101 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003102 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003103 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003104 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003105 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003106 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003107 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003108 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003109 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003110 execute( TC_attach_restart_ctr_echo() );
3111 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003112 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003113 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3114 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003115 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003116 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003117 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003118
Harald Welte2aaac1b2019-05-02 10:02:53 +02003119 execute( TC_xid_empty_l3() );
3120 execute( TC_xid_n201u() );
3121
Harald Weltea05b8072019-04-23 22:35:05 +02003122 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003123 execute( TC_llc_sabm_dm_llgmm() );
3124 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003125
Harald Welte8e5932e2020-06-17 22:12:54 +02003126 execute( TC_suspend_nopaging() );
3127 execute( TC_suspend_resume() );
3128 execute( TC_suspend_rau() );
3129 execute( TC_paging_ps() );
3130
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003131 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3132 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003133}
Harald Welte96a33b02018-02-04 10:36:22 +01003134
3135
3136
3137}