blob: abbcb6480fd9da8dbfee95914cc3a93ddee853d0 [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 {
Alexander Couzense0f7c542020-09-13 17:25:18 +020071 address_family := AF_INET,
Alexander Couzensf3c1b412018-08-24 00:42:51 +020072 local_udp_port := 21010,
73 local_ip := "127.0.0.1",
74 remote_udp_port := 23000,
75 remote_ip := "127.0.0.1",
76 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020077 nsei := 96,
78 role_sgsn := false,
79 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020080 },
81 {
Alexander Couzense0f7c542020-09-13 17:25:18 +020082 address_family := AF_INET,
Alexander Couzensf3c1b412018-08-24 00:42:51 +020083 local_udp_port := 21011,
84 local_ip := "127.0.0.1",
85 remote_udp_port := 23000,
86 remote_ip := "127.0.0.1",
87 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020088 nsei := 97,
89 role_sgsn := false,
90 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020091 },
92 {
Alexander Couzense0f7c542020-09-13 17:25:18 +020093 address_family := AF_INET,
Alexander Couzensf3c1b412018-08-24 00:42:51 +020094 local_udp_port := 21012,
95 local_ip := "127.0.0.1",
96 remote_udp_port := 23000,
97 remote_ip := "127.0.0.1",
98 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020099 nsei := 98,
100 role_sgsn := false,
101 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200102 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200103 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200104
105 RAN_Configurations mp_ranap_cfg := {
106 {
107 transport := RANAP_TRANSPORT_IuCS,
108 sccp_service_type := "mtp3_itu",
109 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
110 own_pc := 195,
111 own_ssn := 142,
112 peer_pc := 188, /* 0.23.4 */
113 peer_ssn := 142,
114 sio := '83'O,
115 rctx := 2
116 }
117 }
Harald Welte5ac31492018-02-15 20:39:13 +0100118};
119
120type record GbInstance {
121 NS_CT vc_NS,
122 BSSGP_CT vc_BSSGP,
123 BssgpConfig cfg
124};
Harald Welte96a33b02018-02-04 10:36:22 +0100125
Harald Welte2fa771f2019-05-02 20:13:53 +0200126const integer NUM_GB := 3;
127type record length(NUM_GB) of GbInstance GbInstances;
128type record length(NUM_GB) of NSConfiguration NSConfigurations;
129type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200130
Harald Welte26fbb6e2019-04-14 17:32:46 +0200131const integer NUM_RNC := 1;
132type record of RAN_Configuration RAN_Configurations;
133
Harald Welte96a33b02018-02-04 10:36:22 +0100134type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200135 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200136 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200137 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100138
Harald Welte5ac31492018-02-15 20:39:13 +0100139 var GSUP_Emulation_CT vc_GSUP;
140 var IPA_Emulation_CT vc_GSUP_IPA;
141 /* only to get events from IPA underneath GSUP */
142 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100143
Harald Welteeded9ad2018-02-17 20:57:34 +0100144 var GTP_Emulation_CT vc_GTP;
145
Harald Weltebd194722018-02-16 22:11:08 +0100146 port TELNETasp_PT SGSNVTY;
147
Harald Welte96a33b02018-02-04 10:36:22 +0100148 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200149 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100150};
151
Harald Welte26fbb6e2019-04-14 17:32:46 +0200152type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100153 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100154 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200155 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100156}
157
158type record SGSN_ConnHdlrNetworkPars {
159 boolean expect_ptmsi,
160 boolean expect_auth,
161 boolean expect_ciph
162};
163
164type record BSSGP_ConnHdlrPars {
165 /* IMEI of the simulated ME */
166 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200167 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100168 hexstring imsi,
169 /* MSISDN of the simulated MS (probably unused) */
170 hexstring msisdn,
171 /* P-TMSI allocated to the simulated MS */
172 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100173 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100174 /* TLLI of the simulated MS */
175 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100176 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100177 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200178 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200179 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
180 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100181 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100182 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200183 float t_guard,
184 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200185 SCCP_PAR_Address sccp_addr_local optional,
186 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100187};
188
Alexander Couzens89508702018-07-31 04:16:10 +0200189private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200190 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200191 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
192
193 var RoutingAreaIdentificationV ret := {
194 mccDigit1 := mcc_mnc[0],
195 mccDigit2 := mcc_mnc[1],
196 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200197 mncDigit3 := mcc_mnc[3],
198 mncDigit1 := mcc_mnc[4],
199 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200200 lac := int2oct(cell_id.ra_id.lai.lac, 16),
201 rac := int2oct(cell_id.ra_id.rac, 8)
202 }
203 return ret;
204};
205
Alexander Couzens51114d12018-07-31 18:41:56 +0200206private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
207 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
208 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100209 /* connect lower end of BSSGP emulation with NS upper port */
210 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100211
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200212 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100213 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
214}
215
216private function f_init_gsup(charstring id) runs on test_CT {
217 id := id & "-GSUP";
218 var GsupOps ops := {
219 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
220 };
221
222 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
223 vc_GSUP := GSUP_Emulation_CT.create(id);
224
225 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
226 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
227 /* we use this hack to get events like ASP_IPA_EVENT_UP */
228 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
229
230 vc_GSUP.start(GSUP_Emulation.main(ops, id));
231 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
232
233 /* wait for incoming connection to GSUP port before proceeding */
234 timer T := 10.0;
235 T.start;
236 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700237 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100238 [] T.timeout {
239 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200240 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100241 }
242 }
243}
244
Harald Welteeded9ad2018-02-17 20:57:34 +0100245private function f_init_gtp(charstring id) runs on test_CT {
246 id := id & "-GTP";
247
248 var GtpEmulationCfg gtp_cfg := {
249 gtpc_bind_ip := mp_ggsn_ip,
250 gtpc_bind_port := GTP1C_PORT,
251 gtpu_bind_ip := mp_ggsn_ip,
252 gtpu_bind_port := GTP1U_PORT,
253 sgsn_role := false
254 };
255
256 vc_GTP := GTP_Emulation_CT.create(id);
257 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
258}
259
Harald Weltebd194722018-02-16 22:11:08 +0100260private function f_init_vty() runs on test_CT {
261 map(self:SGSNVTY, system:SGSNVTY);
262 f_vty_set_prompts(SGSNVTY);
263 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200264 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100265 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
266}
267
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200268private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
269 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200270 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200271 } else {
272 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
273 }
274}
275
Harald Weltebd194722018-02-16 22:11:08 +0100276
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200277/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
278function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200279 var integer i;
280
Harald Welte96a33b02018-02-04 10:36:22 +0100281 if (g_initialized == true) {
282 return;
283 }
284 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100285 g_gb[0].cfg := {
286 nsei := 96,
287 bvci := 196,
288 cell_id := {
289 ra_id := {
290 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100291 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100292 rac := 0
293 },
294 cell_id := 20960
295 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200296 sgsn_role := false,
297 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100298 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200299 g_gb[1].cfg := {
300 nsei := 97,
301 bvci := 210,
302 cell_id := {
303 ra_id := {
304 lai := {
305 mcc_mnc := mcc_mnc, lac := 13200},
306 rac := 0
307 },
308 cell_id := 20961
309 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200310 sgsn_role := false,
311 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200312 };
313 g_gb[2].cfg := {
314 nsei := 98,
315 bvci := 220,
316 cell_id := {
317 ra_id := {
318 lai := {
319 mcc_mnc := mcc_mnc, lac := 13300},
320 rac := 0
321 },
322 cell_id := 20962
323 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200324 sgsn_role := false,
325 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200326 };
Harald Welte96a33b02018-02-04 10:36:22 +0100327
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200328 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200329 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
330 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
331 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200332
Alexander Couzens1552e792019-07-23 20:38:39 +0200333 if (g_ranap_enable) {
334 for (i := 0; i < NUM_RNC; i := i+1) {
335 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
336 f_ran_adapter_start(g_ranap[i]);
337 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200338 }
Harald Welte5ac31492018-02-15 20:39:13 +0100339 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100340 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200341 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100342}
Harald Welte96a33b02018-02-04 10:36:22 +0100343
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200344function f_cleanup() runs on test_CT {
345 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200346 if (g_ranap_enable) {
347 for (i := 0; i < NUM_RNC; i := i+1) {
348 f_ran_adapter_cleanup(g_ranap[i]);
349 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200350 }
351 self.stop;
352}
353
Harald Welte26fbb6e2019-04-14 17:32:46 +0200354private function RncUnitdataCallback(RANAP_PDU ranap)
355runs on RAN_Emulation_CT return template RANAP_PDU {
356 var template RANAP_PDU resp := omit;
357
358 log ("RANAP_RncUnitDataCallback");
359 /* answer all RESET with RESET ACK */
360 if (match(ranap, tr_RANAP_Reset)) {
361 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
362 var CN_DomainIndicator dom;
363 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
364 resp := ts_RANAP_ResetAck(dom);
365 }
366 return resp;
367}
368
369const RanOps RNC_RanOps := {
370 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
371 ranap_unitdata_cb := refers(RncUnitdataCallback),
372 ps_domain := true,
373 decode_dtap := true,
374 role_ms := true,
375 protocol := RAN_PROTOCOL_RANAP,
376 transport := RANAP_TRANSPORT_IuCS,
377 use_osmux := false,
378 sccp_addr_local := omit,
379 sccp_addr_peer := omit
380};
381
Harald Welte5ac31492018-02-15 20:39:13 +0100382type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
383
384/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200385function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100386 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100387runs on test_CT return BSSGP_ConnHdlr {
388 var BSSGP_ConnHdlr vc_conn;
389 var SGSN_ConnHdlrNetworkPars net_pars := {
390 expect_ptmsi := true,
391 expect_auth := true,
392 expect_ciph := false
393 };
394 var BSSGP_ConnHdlrPars pars := {
395 imei := f_gen_imei(imsi_suffix),
396 imsi := f_gen_imsi(imsi_suffix),
397 msisdn := f_gen_msisdn(imsi_suffix),
398 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100399 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100400 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100401 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100402 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200403 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 +0200404 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100405 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100406 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200407 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200408 sccp_addr_local := omit,
409 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100410 };
411
Alexander Couzens1552e792019-07-23 20:38:39 +0200412 if (g_ranap_enable) {
413 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
414 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
415 }
416
Harald Welte5ac31492018-02-15 20:39:13 +0100417 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200418 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200419 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200420 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
421 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200422 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200423 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
424 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200425 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200426 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100427
Harald Welte26fbb6e2019-04-14 17:32:46 +0200428 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200429 if (g_ranap_enable) {
430 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
431 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
432 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200433
Harald Welte5ac31492018-02-15 20:39:13 +0100434 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
435 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
436
Harald Welteeded9ad2018-02-17 20:57:34 +0100437 connect(vc_conn:GTP, vc_GTP:CLIENT);
438 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
439
Harald Welte5ac31492018-02-15 20:39:13 +0100440 vc_conn.start(f_handler_init(fn, id, pars));
441 return vc_conn;
442}
443
Harald Welte62e29582018-02-16 21:17:11 +0100444private altstep as_Tguard() runs on BSSGP_ConnHdlr {
445 [] g_Tguard.timeout {
446 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200447 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100448 }
449}
450
Harald Welte5ac31492018-02-15 20:39:13 +0100451/* first function called in every ConnHdlr */
452private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
453runs on BSSGP_ConnHdlr {
454 /* do some common stuff like setting up g_pars */
455 g_pars := pars;
456
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200457 llc := f_llc_create(false);
458
Harald Welte5ac31492018-02-15 20:39:13 +0100459 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200460 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100461 /* tell GSUP dispatcher to send this IMSI to us */
462 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100463 /* tell GTP dispatcher to send this IMSI to us */
464 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100465
Harald Welte62e29582018-02-16 21:17:11 +0100466 g_Tguard.start(pars.t_guard);
467 activate(as_Tguard());
468
Harald Welte5ac31492018-02-15 20:39:13 +0100469 /* call the user-supplied test case function */
470 fn.apply(id);
471 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100472}
473
474/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100475 * Detach without Attach
476 * SM procedures without attach / RAU
477 * ATTACH / RAU
478 ** with / without authentication
479 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100480 * re-transmissions of LLC frames
481 * PDP Context activation
482 ** with different GGSN config in SGSN VTY
483 ** with different PDP context type (v4/v6/v46)
484 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100485 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100486 */
487
488testcase TC_wait_ns_up() runs on test_CT {
489 f_init();
490 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200491 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100492}
493
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200494friend function is_gb(integer ran_index) return boolean {
495 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200496}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200497friend function is_iu(integer ran_index) return boolean {
498 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200499}
500
Alexander Couzens0507ec32019-09-15 22:41:22 +0200501function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200502 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200503 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 +0200504}
505
Alexander Couzens0507ec32019-09-15 22:41:22 +0200506private 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 +0200507 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
508 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
509 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200510 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200511}
512
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200513/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
514function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
515 log("Sending InitialUE: ", l3_mo);
516 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
517 var RANAP_PDU ranap;
518 var LAI lai := {
519 pLMNidentity := '62F224'O,
520 lAC := '1234'O,
521 iE_Extensions := omit
522 };
523 var SAI sai := {
524 pLMNidentity := lai.pLMNidentity,
525 lAC := lai.lAC,
526 sAC := '0000'O, /* FIXME */
527 iE_Extensions := omit
528 };
529 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
530 var GlobalRNC_ID grnc_id := {
531 pLMNidentity := lai.pLMNidentity,
532 rNC_ID := 2342 /* FIXME */
533 };
534
535 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
536 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
537 alt {
538 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
539 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
540 setverdict(fail, "DISC.ind from SCCP");
541 mtc.stop;
542 }
543 }
544}
545
546/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200547function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
548 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200549 if (g_pars.rnc_send_initial_ue) {
550 g_pars.rnc_send_initial_ue := false;
551 f_send_l3_initial_ue(l3_mo);
552 } else {
553 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
554 }
555 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200556 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200557 }
558}
559
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200560altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700561 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200562 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100563 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200564 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100565 repeat;
566 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200567 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200568 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200569 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200570 repeat;
571 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200572 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100573 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200574 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200575 repeat;
576 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200577 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200578 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200579 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100580 repeat;
581 }
582}
Harald Welte96a33b02018-02-04 10:36:22 +0100583
Harald Welteca362462019-05-02 20:11:21 +0200584/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200585function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200586runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200587 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200588 var PDU_L3_SGSN_MS l3_mt;
589 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200590 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
591 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200592 l3_mt := mt.dtap;
593 }
Harald Welteca362462019-05-02 20:11:21 +0200594 }
595 return l3_mt;
596}
597
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200598/* perform GMM authentication (if expected).
599 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
600 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200601function 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 +0100602 var PDU_L3_MS_SGSN l3_mo;
603 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200604 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100605 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200606 var GSUP_IE auth_tuple;
607 var template AuthenticationParameterAUTNTLV autn;
608
609 if (umts_aka_challenge) {
610 g_pars.vec := f_gen_auth_vec_3g();
611 autn := {
612 elementIdentifier := '28'O,
613 lengthIndicator := lengthof(g_pars.vec.autn),
614 autnValue := g_pars.vec.autn
615 };
616
617 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
618 g_pars.vec.sres,
619 g_pars.vec.kc,
620 g_pars.vec.ik,
621 g_pars.vec.ck,
622 g_pars.vec.autn,
623 g_pars.vec.res));
624 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
625 } else {
626 g_pars.vec := f_gen_auth_vec_2g();
627 autn := omit;
628 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
629 g_pars.vec.sres,
630 g_pars.vec.kc));
631 log("GSUP sends only 2G auth tuple", auth_tuple);
632 }
Harald Welteca362462019-05-02 20:11:21 +0200633
Harald Welte5ac31492018-02-15 20:39:13 +0100634 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
635 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200636
637 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
638 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200639 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100640 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200641 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
642
643 if (umts_aka_challenge and not force_gsm_sres) {
644 /* set UMTS response instead */
645 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
646 valueField := substr(g_pars.vec.res, 0, 4)
647 };
648 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
649 elementIdentifier := '21'O,
650 lengthIndicator := lengthof(g_pars.vec.res) - 4,
651 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
652 };
653 }
654
655 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100656 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
657 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
658 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
659 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
660 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200661 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200662
663 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200664 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200665 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
666 key_sts := ?)) {
667 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
668 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200669 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200670 }
671 }
Harald Welte76dee092018-02-16 22:12:59 +0100672 } else {
673 /* wait for identity procedure */
674 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100675 }
Harald Welte76dee092018-02-16 22:12:59 +0100676
Harald Welte5ac31492018-02-15 20:39:13 +0100677 deactivate(di);
678}
679
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200680function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100681 g_pars.p_tmsi := p_tmsi;
682 /* update TLLI */
683 g_pars.tlli_old := g_pars.tlli;
684 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100685 if (is_gb(ran_index)) {
686 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
687 }
Harald Weltef70997d2018-02-17 10:11:19 +0100688}
689
Harald Welte04683d02018-02-16 22:43:45 +0100690function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
691 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100692 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200693 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100694 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200695 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200696 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100697 }
Harald Welte04683d02018-02-16 22:43:45 +0100698 g_pars.ra := aa.routingAreaIdentification;
699 if (ispresent(aa.allocatedPTMSI)) {
700 if (not g_pars.net.expect_ptmsi) {
701 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200702 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100703 }
Harald Weltef70997d2018-02-17 10:11:19 +0100704 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100705 }
706 if (ispresent(aa.msIdentity)) {
707 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200708 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100709 }
710 /* P-TMSI.sig */
711 if (ispresent(aa.ptmsiSignature)) {
712 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
713 }
714 /* updateTimer */
715 // aa.readyTimer
716 /* T3302, T3319, T3323, T3312_ext, T3324 */
717}
718
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200719function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100720 /* mandatory IE */
721 g_pars.ra := ra.routingAreaId;
722 if (ispresent(ra.allocatedPTMSI)) {
723 if (not g_pars.net.expect_ptmsi) {
724 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200725 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100726 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200727 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100728 }
729 if (ispresent(ra.msIdentity)) {
730 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200731 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100732 }
733 /* P-TMSI.sig */
734 if (ispresent(ra.ptmsiSignature)) {
735 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
736 }
737 /* updateTimer */
738 // aa.readyTimer
739 /* T3302, T3319, T3323, T3312_ext, T3324 */
740}
741
742
Harald Welte5a4fa042018-02-16 20:59:21 +0100743function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
744 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
745}
746
Harald Welte23178c52018-02-17 09:36:33 +0100747/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700748private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100749 if (ispresent(g_pars.p_tmsi)) {
750 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
751 } else {
752 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
753 }
754}
755
Harald Welte311ec272018-02-17 09:40:03 +0100756private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100757 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100758 /* Expect MSC to perform LU with HLR */
759 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100760 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
761 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
762 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100763 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
764 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
765}
766
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200767friend 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 +0100768 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200769 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 +0200770 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100771
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200772 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
773 * 3G auth vectors */
774 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
775 /* The thing is, if the solSACapability is 'omit', then the
776 * revisionLevelIndicatior is at the wrong place! */
777 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
778
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200779 f_send_l3(attach_req, ran_index);
780 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200781 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100782 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100783
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200784 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200785 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
786
Harald Welte04683d02018-02-16 22:43:45 +0100787 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200788 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200789
790 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200791 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200792 as_iu_release_compl_disc();
793 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200794
795 /* Race condition
796 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
797 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
798 * arrived before it. This results in a test case failure.
799 * Delay execution by 50 ms
800 */
801 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200802}
803
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200804friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
805 timer T := 5.0;
806 var PDU_BSSGP rx_pdu;
807 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
808 T.start;
809 alt {
810 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
811 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
812 }
813 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
814 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
815 mtc.stop;
816 }
817 [] T.timeout {
818 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
819 mtc.stop;
820 }
821 }
822 return '00'O;
823}
824
825friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
826 timer T := 5.0;
827 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
828 T.start;
829 alt {
830 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
831 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
832?)) {
833 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
834 mtc.stop;
835 }
836 [] T.timeout {
837 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
838 mtc.stop;
839 }
840 }
841}
842
843
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200844private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
845 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100846 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100847}
848
849testcase TC_attach() runs on test_CT {
850 var BSSGP_ConnHdlr vc_conn;
851 f_init();
852 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200853 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100854 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200855 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100856}
857
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100858testcase TC_attach_mnc3() runs on test_CT {
859 var BSSGP_ConnHdlr vc_conn;
860 f_init('023042'H);
861 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200862 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100863 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200864 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100865}
866
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200867private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
868 f_gmm_attach(true, false);
869 setverdict(pass);
870}
871testcase TC_attach_umts_aka_umts_res() runs on test_CT {
872 var BSSGP_ConnHdlr vc_conn;
873 f_init();
874 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200875 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200876 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200877 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200878}
879
880private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
881 f_gmm_attach(true, true);
882 setverdict(pass);
883}
884testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
885 var BSSGP_ConnHdlr vc_conn;
886 f_init();
887 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200888 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200889 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200890 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200891}
892
Harald Welte5b7c8122018-02-16 21:48:17 +0100893/* MS never responds to ID REQ, expect ATTACH REJECT */
894private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100895 var RoutingAreaIdentificationV old_ra := f_random_RAI();
896
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200897 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100898 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200899 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100900 /* don't send ID Response */
901 repeat;
902 }
Harald Welte955aa942019-05-03 01:29:29 +0200903 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100904 setverdict(pass);
905 }
Harald Welte955aa942019-05-03 01:29:29 +0200906 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100907 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200908 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100909 }
910 }
911}
912testcase TC_attach_auth_id_timeout() runs on test_CT {
913 var BSSGP_ConnHdlr vc_conn;
914 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200915 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 +0100916 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200917 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100918}
919
920/* HLR never responds to SAI REQ, expect ATTACH REJECT */
921private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100922 var RoutingAreaIdentificationV old_ra := f_random_RAI();
923
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200924 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100925 alt {
926 [] as_mm_identity();
927 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
928 }
929 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200930 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100931 setverdict(pass);
932}
933testcase TC_attach_auth_sai_timeout() runs on test_CT {
934 var BSSGP_ConnHdlr vc_conn;
935 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200936 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100937 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200938 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100939}
940
Harald Weltefe253882018-02-17 09:25:00 +0100941/* HLR rejects SAI, expect ATTACH REJECT */
942private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100943 var RoutingAreaIdentificationV old_ra := f_random_RAI();
944
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200945 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100946 alt {
947 [] as_mm_identity();
948 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
949 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
950 }
951 }
Harald Welte955aa942019-05-03 01:29:29 +0200952 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100953 setverdict(pass);
954}
955testcase TC_attach_auth_sai_reject() runs on test_CT {
956 var BSSGP_ConnHdlr vc_conn;
957 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200958 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100959 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200960 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100961}
962
Harald Welte5b7c8122018-02-16 21:48:17 +0100963/* HLR never responds to UL REQ, expect ATTACH REJECT */
964private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200965 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100966 var RoutingAreaIdentificationV old_ra := f_random_RAI();
967
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200968 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100969 f_gmm_auth();
970 /* Expect MSC to perform LU with HLR */
971 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
972 /* Never follow-up with ISD_REQ or UL_RES */
973 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200974 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100975 setverdict(pass);
976 }
Harald Welte955aa942019-05-03 01:29:29 +0200977 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
978 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100979 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200980 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100981 }
982 }
983}
984testcase TC_attach_gsup_lu_timeout() runs on test_CT {
985 var BSSGP_ConnHdlr vc_conn;
986 f_init();
987 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200988 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100989 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200990 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100991}
992
Harald Welteb7c14e92018-02-17 09:29:16 +0100993/* HLR rejects UL REQ, expect ATTACH REJECT */
994private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200995 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100996 var RoutingAreaIdentificationV old_ra := f_random_RAI();
997
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200998 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100999 f_gmm_auth();
1000 /* Expect MSC to perform LU with HLR */
1001 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1002 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1003 }
1004 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001005 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001006 setverdict(pass);
1007 }
Harald Welte955aa942019-05-03 01:29:29 +02001008 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1009 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001010 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001011 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001012 }
1013 }
1014}
1015testcase TC_attach_gsup_lu_reject() runs on test_CT {
1016 var BSSGP_ConnHdlr vc_conn;
1017 f_init();
1018 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001019 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001020 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001021 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001022}
1023
1024
Harald Welte3823e2e2018-02-16 21:53:48 +01001025/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1026private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001027 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001028 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1029
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001030 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001031 f_gmm_auth();
1032 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001033 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001034
Harald Welte955aa942019-05-03 01:29:29 +02001035 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1036 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001037 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001038 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001039 setverdict(pass);
1040}
Harald Welte3823e2e2018-02-16 21:53:48 +01001041testcase TC_attach_combined() runs on test_CT {
1042 var BSSGP_ConnHdlr vc_conn;
1043 f_init();
1044 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001045 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001046 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001047 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001048}
1049
Harald Welte76dee092018-02-16 22:12:59 +01001050/* Attempt of GPRS ATTACH in 'accept all' mode */
1051private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001052 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001053 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1054
1055 g_pars.net.expect_auth := false;
1056
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001057 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001058 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001059 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1060 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001061 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001062 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001063 setverdict(pass);
1064}
1065testcase TC_attach_accept_all() runs on test_CT {
1066 var BSSGP_ConnHdlr vc_conn;
1067 f_init();
1068 f_sleep(1.0);
1069 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001070 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001071 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001072 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001073}
Harald Welte5b7c8122018-02-16 21:48:17 +01001074
Harald Welteb2124b22018-02-16 22:26:56 +01001075/* Attempt of GPRS ATTACH in 'accept all' mode */
1076private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001077 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1078
1079 /* Simulate a foreign IMSI */
1080 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001081 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001082
1083 g_pars.net.expect_auth := false;
1084
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001085 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001086 alt {
1087 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001088 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001089 setverdict(pass);
1090 }
Harald Welte955aa942019-05-03 01:29:29 +02001091 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001092 setverdict(pass);
1093 }
Harald Welte955aa942019-05-03 01:29:29 +02001094 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001095 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001096 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001097 }
Harald Welteb2124b22018-02-16 22:26:56 +01001098 }
1099}
1100testcase TC_attach_closed() runs on test_CT {
1101 var BSSGP_ConnHdlr vc_conn;
1102 f_init();
1103 f_sleep(1.0);
1104 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1105 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001106 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001107 vc_conn.done;
1108 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001109 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001110 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001111 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001112}
1113
Harald Welte04683d02018-02-16 22:43:45 +01001114/* Routing Area Update from Unknown TLLI -> REJECT */
1115private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001116 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1117
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001118 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 +01001119 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001120 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001121 setverdict(pass);
1122 }
1123 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001124 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001125 }
1126}
1127testcase TC_rau_unknown() runs on test_CT {
1128 var BSSGP_ConnHdlr vc_conn;
1129 f_init();
1130 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001131 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001132 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001133 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001134}
1135
Harald Welte91636de2018-02-17 10:16:14 +01001136private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001137 /* first perform regular attach */
1138 f_TC_attach(id);
1139
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001140 f_routing_area_update(g_pars.ra);
1141
Harald Welte91636de2018-02-17 10:16:14 +01001142}
1143testcase TC_attach_rau() runs on test_CT {
1144 var BSSGP_ConnHdlr vc_conn;
1145 f_init();
1146 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001147 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001148 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001149 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001150}
Harald Welte04683d02018-02-16 22:43:45 +01001151
Harald Welte6abb9fe2018-02-17 15:24:48 +01001152/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001153function 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 +02001154 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001155 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001156 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001157 if (expect_purge) {
1158 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1159 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1160 }
1161 T.start;
1162 alt {
1163 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1164 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001165 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001166 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001167 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001168 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001169 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001170 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001171 /* TODO: check if any PDP contexts are deactivated on network side? */
1172 }
1173 [power_off] T.timeout {
1174 setverdict(pass);
1175 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001176 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001177 g_pars.ra := omit;
1178 setverdict(pass);
1179 /* TODO: check if any PDP contexts are deactivated on network side? */
1180 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001181 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001182 if (power_off) {
1183 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1184 } else {
1185 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1186 }
1187 mtc.stop;
1188 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001189 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001190 }
1191}
1192
1193/* IMSI DETACH (non-power-off) for unknown TLLI */
1194private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1195 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1196}
1197testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1198 var BSSGP_ConnHdlr vc_conn;
1199 f_init();
1200 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001201 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001202 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001203 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001204}
1205
1206/* IMSI DETACH (power-off) for unknown TLLI */
1207private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1208 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1209}
1210testcase TC_detach_unknown_poweroff() runs on test_CT {
1211 var BSSGP_ConnHdlr vc_conn;
1212 f_init();
1213 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001214 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001215 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001216 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001217}
1218
1219/* IMSI DETACH (non-power-off) for known TLLI */
1220private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1221 /* first perform regular attach */
1222 f_TC_attach(id);
1223
1224 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1225}
1226testcase TC_detach_nopoweroff() runs on test_CT {
1227 var BSSGP_ConnHdlr vc_conn;
1228 f_init();
1229 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001230 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001231 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001232 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001233}
1234
1235/* IMSI DETACH (power-off) for known TLLI */
1236private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1237 /* first perform regular attach */
1238 f_TC_attach(id);
1239
1240 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1241}
1242testcase TC_detach_poweroff() runs on test_CT {
1243 var BSSGP_ConnHdlr vc_conn;
1244 f_init();
1245 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001246 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001247 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001248 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001249}
1250
Harald Welteeded9ad2018-02-17 20:57:34 +01001251type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001252 BIT3 tid, /* L3 Transaction ID */
1253 BIT4 nsapi, /* SNDCP NSAPI */
1254 BIT4 sapi, /* LLC SAPI */
1255 QoSV qos, /* QoS parameters */
1256 PDPAddressV addr, /* IP address */
1257 octetstring apn optional, /* APN name */
1258 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1259 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001260 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001261 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001262
Harald Welte822f9102018-02-18 20:39:06 +01001263 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1264 OCT4 ggsn_tei_u, /* GGSN TEI User */
1265 octetstring ggsn_ip_c, /* GGSN IP Control */
1266 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001267 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001268
Harald Welte822f9102018-02-18 20:39:06 +01001269 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1270 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1271 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1272 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001273};
1274
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001275
1276private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1277 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1278 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1279 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1280 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1281 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1282 f_gtp_register_teid(apars.ggsn_tei_c);
1283 f_gtp_register_teid(apars.ggsn_tei_u);
1284}
1285
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001286function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001287runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001288 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1289 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001290 var template Recovery_gtpc recovery := omit;
1291
1292 if (send_recovery) {
1293 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1294 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001295
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001296 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 +02001297 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001298 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1299 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1300 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1301 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1302 apars.sgsn_tei_c, apars.gtp_resp_cause,
1303 apars.ggsn_tei_c, apars.ggsn_tei_u,
1304 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001305 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1306 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001307 }
1308 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001309 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001310 setverdict(pass);
1311 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001312 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001313 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001314 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001315 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001316 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001317 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001318 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001319 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001320 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001321 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1322 mtc.stop;
1323 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001324 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001325 setverdict(pass);
1326 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001327 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001328 }
1329}
1330
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001331function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001332runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001333 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1334 var Gtp1cUnitdata g_ud;
1335
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001336 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001337 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1338 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001339 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001340 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1341 }
1342 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001343 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001344 setverdict(pass);
1345 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001346 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001347 }
1348}
1349
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001350function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001351runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001352 var Gtp1cUnitdata g_ud;
1353 var integer seq_nr := 23;
1354 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1355
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001356 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001357 if (error_ind) {
1358 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1359 } else {
1360 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1361 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001362
1363 timer T := 5.0;
1364 T.start;
1365
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001366 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001367 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1368 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001369 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001370 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1371 repeat;
1372 }
1373 [] T.timeout {
1374 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1375 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001376 }
1377}
1378
Harald Welte6f203162018-02-18 22:04:55 +01001379
Harald Welteeded9ad2018-02-17 20:57:34 +01001380/* Table 10.5.156/3GPP TS 24.008 */
1381template (value) QoSV t_QosDefault := {
1382 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1383 delayClass := '100'B, /* best effort */
1384 spare1 := '00'B,
1385 precedenceClass := '010'B, /* normal */
1386 spare2 := '0'B,
1387 peakThroughput := '0000'B, /* subscribed */
1388 meanThroughput := '00000'B, /* subscribed */
1389 spare3 := '000'B,
1390 deliverErroneusSDU := omit,
1391 deliveryOrder := omit,
1392 trafficClass := omit,
1393 maxSDUSize := omit,
1394 maxBitrateUplink := omit,
1395 maxBitrateDownlink := omit,
1396 sduErrorRatio := omit,
1397 residualBER := omit,
1398 trafficHandlingPriority := omit,
1399 transferDelay := omit,
1400 guaranteedBitRateUplink := omit,
1401 guaranteedBitRateDownlink := omit,
1402 sourceStatisticsDescriptor := omit,
1403 signallingIndication := omit,
1404 spare4 := omit,
1405 maxBitrateDownlinkExt := omit,
1406 guaranteedBitRateDownlinkExt := omit,
1407 maxBitrateUplinkExt := omit,
1408 guaranteedBitRateUplinkExt := omit,
1409 maxBitrateDownlinkExt2 := omit,
1410 guaranteedBitRateDownlinkExt2 := omit,
1411 maxBitrateUplinkExt2 := omit,
1412 guaranteedBitRateUplinkExt2 := omit
1413}
1414
1415/* 10.5.6.4 / 3GPP TS 24.008 */
1416template (value) PDPAddressV t_AddrIPv4dyn := {
1417 pdpTypeOrg := '0001'B, /* IETF */
1418 spare := '0000'B,
1419 pdpTypeNum := '21'O, /* IPv4 */
1420 addressInfo := omit
1421}
1422template (value) PDPAddressV t_AddrIPv6dyn := {
1423 pdpTypeOrg := '0001'B, /* IETF */
1424 spare := '0000'B,
1425 pdpTypeNum := '53'O, /* IPv6 */
1426 addressInfo := omit
1427}
1428
Harald Welte37692d82018-02-18 15:21:34 +01001429template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001430 tid := '000'B,
1431 nsapi := '0101'B, /* < 5 are reserved */
1432 sapi := '0011'B, /* 3/5/9/11 */
1433 qos := t_QosDefault,
1434 addr := t_AddrIPv4dyn,
1435 apn := omit,
1436 pco := omit,
1437 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001438 gtp_resp_cause := int2oct(128, 1),
1439 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001440
1441 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001442 ggsn_tei_c := f_rnd_octstring(4),
1443 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001444 ggsn_ip_c := f_inet_addr(ggsn_ip),
1445 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001446 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001447
Harald Welteeded9ad2018-02-17 20:57:34 +01001448 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001449 sgsn_tei_u := omit,
1450 sgsn_ip_c := omit,
1451 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001452}
1453
Harald Welte37692d82018-02-18 15:21:34 +01001454template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1455 connId := 1,
1456 remName := f_inet_ntoa(ip),
1457 remPort := GTP1U_PORT
1458}
1459
1460template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1461 connId := 1,
1462 remName := f_inet_ntoa(ip),
1463 remPort := GTP1C_PORT
1464}
1465
1466private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1467 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1468 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1469}
1470
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001471private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1472 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001473 repeat;
1474 }
1475}
1476
1477template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1478 pDU_SN_UNITDATA := {
1479 nsapi := nsapi,
1480 moreBit := ?,
1481 snPduType := '1'B,
1482 firstSegmentIndicator := ?,
1483 spareBit := ?,
1484 pcomp := ?,
1485 dcomp := ?,
1486 npduNumber := ?,
1487 segmentNumber := ?,
1488 npduNumberContinued := ?,
1489 dataSegmentSnUnitdataPdu := payload
1490 }
1491}
1492
1493/* simple case: single segment, no compression */
1494template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1495 pDU_SN_UNITDATA := {
1496 nsapi := nsapi,
1497 moreBit := '0'B,
1498 snPduType := '1'B,
1499 firstSegmentIndicator := '1'B,
1500 spareBit := '0'B,
1501 pcomp := '0000'B,
1502 dcomp := '0000'B,
1503 npduNumber := '0000'B,
1504 segmentNumber := '0000'B,
1505 npduNumberContinued := '00'O,
1506 dataSegmentSnUnitdataPdu := payload
1507 }
1508}
1509
1510/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001511private 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 +02001512runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001513 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001514 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1515 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001516 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001517 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1518 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001519 [] as_xid(apars, ran_index);
1520 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001521 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1522 [expect_fwd] T.timeout {
1523 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1524 mtc.stop;
1525 }
1526 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1527 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1528 mtc.stop;
1529 }
1530 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001531 }
1532}
1533
Harald Welte64d6b512020-06-17 16:42:00 +02001534/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001535private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001536runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001537 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1538 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1539 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001540 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001541 /* Expect PDU via GTP from SGSN on simulated GGSN */
1542 alt {
1543 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1544 }
1545}
1546
Harald Welteeded9ad2018-02-17 20:57:34 +01001547private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001548 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001549
1550 /* first perform regular attach */
1551 f_TC_attach(id);
1552
1553 f_pdp_ctx_act(apars);
1554}
1555testcase TC_attach_pdp_act() runs on test_CT {
1556 var BSSGP_ConnHdlr vc_conn;
1557 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001558 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001559 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001560 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001561}
Harald Welteb2124b22018-02-16 22:26:56 +01001562
Harald Welte835b15f2018-02-18 14:39:11 +01001563/* PDP Context activation for not-attached subscriber; expect fail */
1564private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001565 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001566 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 +01001567 apars.apn, apars.pco));
1568 alt {
1569 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001570 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001571 setverdict(pass);
1572 }
1573 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1574 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001575 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001576 }
Harald Welte955aa942019-05-03 01:29:29 +02001577 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001578 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001579 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001580 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001581 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001582 }
1583}
1584testcase TC_pdp_act_unattached() runs on test_CT {
1585 var BSSGP_ConnHdlr vc_conn;
1586 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001587 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001588 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001589 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001590}
1591
Harald Welte37692d82018-02-18 15:21:34 +01001592/* ATTACH + PDP CTX ACT + user plane traffic */
1593private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1594 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1595
1596 /* first perform regular attach */
1597 f_TC_attach(id);
1598 /* then activate PDP context */
1599 f_pdp_ctx_act(apars);
1600 /* then transceive a downlink PDU */
1601 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1602 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1603}
1604testcase TC_attach_pdp_act_user() runs on test_CT {
1605 var BSSGP_ConnHdlr vc_conn;
1606 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001607 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001608 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001609 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001610}
1611
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001612/* ATTACH + PDP CTX ACT; reject from GGSN */
1613private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1614 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1615
1616 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1617 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1618
1619 /* first perform regular attach */
1620 f_TC_attach(id);
1621 /* then activate PDP context */
1622 f_pdp_ctx_act(apars);
1623}
1624testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1625 var BSSGP_ConnHdlr vc_conn;
1626 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001627 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001628 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001629 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001630}
Harald Welte835b15f2018-02-18 14:39:11 +01001631
Harald Welte6f203162018-02-18 22:04:55 +01001632/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1633private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1634 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1635
1636 /* first perform regular attach */
1637 f_TC_attach(id);
1638 /* then activate PDP context */
1639 f_pdp_ctx_act(apars);
1640 /* then transceive a downlink PDU */
1641 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1642 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1643
1644 f_pdp_ctx_deact_mo(apars, '00'O);
1645}
1646testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1647 var BSSGP_ConnHdlr vc_conn;
1648 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001649 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 +01001650 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001651 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001652}
1653
Harald Welte57b9b7f2018-02-18 22:28:13 +01001654/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1655private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1656 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1657
1658 /* first perform regular attach */
1659 f_TC_attach(id);
1660 /* then activate PDP context */
1661 f_pdp_ctx_act(apars);
1662 /* then transceive a downlink PDU */
1663 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1664 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1665
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001666 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001667}
1668testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1669 var BSSGP_ConnHdlr vc_conn;
1670 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001671 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 +01001672 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001673 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001674}
1675
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001676/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1677private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1678 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1679 var Gtp1cUnitdata g_ud;
1680 var integer i;
1681 var OCT1 cause_regular_deact := '24'O;
1682
1683 /* first perform regular attach + PDP context act */
1684 f_TC_attach(id);
1685 f_pdp_ctx_act(apars);
1686
1687 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1688 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1689
1690 for (i := 0; i < 2; i := i+1) {
1691 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1692 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1693 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1694 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1695 }
1696 }
1697
1698 alt {
1699 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1700 setverdict(pass);
1701 }
1702 [] as_xid(apars, 0);
1703 }
1704
1705 /* Make sure second DeactPdpAccept is sent: */
1706 timer T := 2.0;
1707 T.start;
1708 alt {
1709 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1710 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1711 }
1712 [] T.timeout {
1713 setverdict(pass);
1714 }
1715 }
1716
1717 setverdict(pass);
1718}
1719testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1720 var BSSGP_ConnHdlr vc_conn;
1721 f_init();
1722 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1723 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001724 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001725}
1726
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001727/* ATTACH + ATTACH (2nd) */
1728private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1729 g_pars.t_guard := 5.0;
1730
1731 /* first perform regular attach */
1732 f_TC_attach(id);
1733
1734 /* second to perform regular attach */
1735 f_TC_attach(id);
1736}
1737
1738
1739testcase TC_attach_second_attempt() runs on test_CT {
1740 var BSSGP_ConnHdlr vc_conn;
1741 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001742 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001743 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001744 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001745}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001746
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001747private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1748 var Gtp1cUnitdata g_ud;
1749 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1750 var integer seq_nr;
1751
1752 /* first perform regular attach */
1753 f_TC_attach(id);
1754 /* then activate PDP context */
1755 f_pdp_ctx_act(apars);
1756
1757 /* Wait to receive first echo request and send initial Restart counter */
1758 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1759 BSSGP[0].clear;
1760 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1761 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1762 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1763 }
1764
1765 /* At some point next echo request not answered will timeout and SGSN
1766 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1767 timer T := 3.0 * 6.0 + 16.0;
1768 T.start;
1769 alt {
1770 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1771 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1772 setverdict(pass);
1773 }
1774 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1775 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1776 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1777 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1778 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1779 repeat;
1780 }
1781 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1782 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1783 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1784 repeat;
1785 }
1786 [] T.timeout {
1787 setverdict(fail, "BSSGP DeactPdpReq not received");
1788 mtc.stop;
1789 }
1790 [] as_xid(apars);
1791 }
1792 T.stop
1793
1794 setverdict(pass);
1795}
1796/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1797testcase TC_attach_echo_timeout() runs on test_CT {
1798 var BSSGP_ConnHdlr vc_conn;
1799 g_use_echo := true;
1800 f_init();
1801 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1802 vc_conn.done;
1803 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001804 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001805}
1806
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001807private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001808 var Gtp1cUnitdata g_ud;
1809 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1810
1811 /* first perform regular attach */
1812 f_TC_attach(id);
1813 /* Activate a pdp context against the GGSN */
1814 f_pdp_ctx_act(apars);
1815 /* Wait to receive first echo request and send initial Restart counter */
1816 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1817 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1818 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1819 }
1820 /* Wait to receive second echo request and send incremented Restart
1821 counter. This will fake a restarted GGSN, and pdp ctx allocated
1822 should be released by SGSN */
1823 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1824 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1825 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1826 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1827 }
1828 var OCT1 cause_network_failure := int2oct(38, 1)
1829 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001830 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001831 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001832 setverdict(pass);
1833 }
1834 [] as_xid(apars);
1835 }
1836 setverdict(pass);
1837}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001838/* ATTACH + trigger Recovery procedure through EchoResp */
1839testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001840 var BSSGP_ConnHdlr vc_conn;
1841 g_use_echo := true
1842 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001843 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 +02001844 vc_conn.done;
1845 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001846 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001847}
1848
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001849private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1850 var Gtp1cUnitdata g_ud;
1851 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1852 var integer seq_nr := 23;
1853 var GtpPeer peer;
1854 /* first perform regular attach */
1855 f_TC_attach(id);
1856
1857 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1858 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1859 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1860 f_pdp_ctx_act(apars, true);
1861
1862 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1863/* received. */
1864 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1865
1866 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1867 would be great to have an active pdp context here before triggering
1868 Recovery, and making sure the the DEACT request is sent by the SGSN.
1869 */
1870
1871 /* Activate a pdp context against the GGSN, send incremented Recovery
1872 IE. This should trigger the recovery path, but still this specific
1873 CTX activation should work. */
1874 apars.exp_rej_cause := omit; /* default value for tests */
1875 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1876 f_pdp_ctx_act(apars, true);
1877
1878 setverdict(pass);
1879}
1880/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1881testcase TC_attach_restart_ctr_create() runs on test_CT {
1882 var BSSGP_ConnHdlr vc_conn;
1883 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001884 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 +02001885 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001886 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001887}
1888
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001889/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1890private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1891 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1892 var integer seq_nr := 23;
1893 var GtpPeer peer;
1894 var integer i;
1895
1896 /* first perform regular attach */
1897 f_TC_attach(id);
1898 /* then activate PDP context */
1899 f_pdp_ctx_act(apars);
1900
Alexander Couzens0e510e62018-07-28 23:06:00 +02001901 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001902 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1903 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1904
1905 for (i := 0; i < 5; i := i+1) {
1906 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001907 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001908 [] as_xid(apars);
1909 }
1910 }
1911
1912 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1913
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001914 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001915 setverdict(pass);
1916}
1917testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1918 var BSSGP_ConnHdlr vc_conn;
1919 f_init();
1920 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001921 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 +02001922 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001923 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001924}
1925
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001926/* ATTACH + PDP CTX ACT dropped + retrans */
1927private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1928 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1929 var Gtp1cUnitdata g_ud_first, g_ud_second;
1930 /* first perform regular attach */
1931 f_TC_attach(id);
1932
1933 /* then activate PDP context on the Gb side */
1934 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1935 apars.apn, apars.pco), 0);
1936
1937 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1938 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1939 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1940 if (g_ud_first != g_ud_second) {
1941 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1942 mtc.stop;
1943 }
1944 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1945 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1946 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1947 apars.sgsn_tei_c, apars.gtp_resp_cause,
1948 apars.ggsn_tei_c, apars.ggsn_tei_u,
1949 apars.nsapi,
1950 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1951 omit, omit));
1952 }
Harald Welte955aa942019-05-03 01:29:29 +02001953 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001954
1955 /* Now the same with Deact */
1956 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1957 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1958 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1959 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1960 if (g_ud_first != g_ud_second) {
1961 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1962 mtc.stop;
1963 }
1964 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1965 BSSGP[0].clear;
1966 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1967 }
1968 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001969 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001970 setverdict(pass);
1971 }
1972 [] as_xid(apars, 0);
1973 }
1974
1975 setverdict(pass);
1976}
1977testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1978 var BSSGP_ConnHdlr vc_conn;
1979 f_init();
1980 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1981 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001982 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001983}
1984
1985/* Test that SGSN GTP response retransmit queue works fine */
1986private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1987 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1988 var integer seq_nr := 23;
1989 var Gtp1cUnitdata g_ud_first, g_ud_second;
1990 var template Gtp1cUnitdata g_delete_req;
1991 /* first perform regular attach + PDP context act */
1992 f_TC_attach(id);
1993 f_pdp_ctx_act(apars);
1994
1995 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1996 BSSGP[0].clear;
1997 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1998 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1999 GTP.send(g_delete_req);
2000 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002001 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002002 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2003 }
2004 [] as_xid(apars, 0);
2005 }
2006 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2007 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2008 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2009 mtc.stop;
2010 }
2011 };
2012
2013 /* Send duplicate DeleteCtxReq */
2014 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2015 GTP.send(g_delete_req);
2016 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2017 if (g_ud_first != g_ud_second) {
2018 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2019 mtc.stop;
2020 }
2021 }
2022
2023 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2024 * is handled differently by SGSN (expect "non-existent" cause) */
2025 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2026 GTP.send(g_delete_req);
2027 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2028 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2029 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2030 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2031 mtc.stop;
2032 }
2033 }
2034
2035 setverdict(pass);
2036}
2037testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2038 var BSSGP_ConnHdlr vc_conn;
2039 f_init();
2040 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2041 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002042 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002043}
2044
Alexander Couzens5e307b42018-05-22 18:12:20 +02002045private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2046 /* MS: perform regular attach */
2047 f_TC_attach(id);
2048
2049 /* HLR: cancel the location request */
2050 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2051 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002052
2053 /* ensure no Detach Request got received */
2054 timer T := 5.0;
2055 T.start;
2056 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002057 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002058 T.stop;
2059 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002060 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002061 }
2062 [] T.timeout {
2063 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002064 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002065 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002066 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002067 repeat;
2068 }
2069 }
2070}
2071
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002072/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2073private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2074 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2075
2076 /* first perform regular attach */
2077 f_TC_attach(id);
2078 /* then activate PDP context */
2079 f_pdp_ctx_act(apars);
2080 /* then transceive a downlink PDU */
2081 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2082
2083 /* Send Error indication as response from upload PDU and expect deact towards MS */
2084 f_pdp_ctx_deact_mt(apars, true);
2085}
2086testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2087 var BSSGP_ConnHdlr vc_conn;
2088 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002089 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 +02002090 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002091 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002092}
2093
Alexander Couzens5e307b42018-05-22 18:12:20 +02002094testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2095 /* MS <-> SGSN: GMM Attach
2096 * HLR -> SGSN: Cancel Location Request
2097 * HLR <- SGSN: Cancel Location Ack
2098 */
2099 var BSSGP_ConnHdlr vc_conn;
2100 f_init();
2101 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002102 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002103 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002104 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002105}
2106
2107
Alexander Couzensc87967a2018-05-22 16:09:54 +02002108private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2109 /* MS: perform regular attach */
2110 f_TC_attach(id);
2111
2112 /* HLR: cancel the location request */
2113 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2114 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2115 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2116
2117 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002118 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002119 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002120
2121 setverdict(pass);
2122}
2123
2124testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2125 /* MS <-> SGSN: GMM Attach
2126 * HLR -> SGSN: Cancel Location Request
2127 * HLR <- SGSN: Cancel Location Ack
2128 * MS <- SGSN: Detach Request
2129 * SGSN-> MS: Detach Complete
2130 */
2131 var BSSGP_ConnHdlr vc_conn;
2132 f_init();
2133 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002134 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002135 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002136 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002137}
2138
2139
Alexander Couzens6c47f292018-05-22 17:09:49 +02002140private function f_hlr_location_cancel_request_unknown_subscriber(
2141 charstring id,
2142 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2143
2144 /* HLR: cancel the location request */
2145 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2146
2147 /* cause 2 = IMSI_UNKNOWN */
2148 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2149
2150 setverdict(pass);
2151}
2152
2153private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002154 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002155}
2156
2157testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2158 /* HLR -> SGSN: Cancel Location Request
2159 * HLR <- SGSN: Cancel Location Error
2160 */
2161
2162 var BSSGP_ConnHdlr vc_conn;
2163 f_init();
2164 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002165 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 +02002166 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002167 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002168}
2169
2170private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002171 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002172}
2173
2174testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2175 /* HLR -> SGSN: Cancel Location Request
2176 * HLR <- SGSN: Cancel Location Error
2177 */
2178
2179 var BSSGP_ConnHdlr vc_conn;
2180 f_init();
2181 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002182 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 +02002183 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002184 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002185}
2186
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002187private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2188 f_TC_attach(id);
2189 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2190}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002191
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002192testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2193 /* MS <-> SGSN: Attach
2194 * MS -> SGSN: Detach Req (Power off)
2195 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2196 */
2197 var BSSGP_ConnHdlr vc_conn;
2198 var integer id := 33;
2199 var charstring imsi := hex2str(f_gen_imsi(id));
2200
2201 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002202 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002203 vc_conn.done;
2204
2205 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002206 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002207}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002208
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002209/* Attempt an attach, but loose the Identification Request (IMEI) */
2210private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2211 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002212 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002213
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002214 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 +02002215
2216 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002217 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002218 /* break */
2219 }
Harald Welte955aa942019-05-03 01:29:29 +02002220 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002221 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002222 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002223 repeat;
2224 }
Harald Welte955aa942019-05-03 01:29:29 +02002225 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002226 /* ignore ID REQ IMEI */
2227 count_req := count_req + 1;
2228 repeat;
2229 }
2230 }
2231 if (count_req != 5) {
2232 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002233 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002234 }
2235 setverdict(pass);
2236}
2237
2238testcase TC_attach_no_imei_response() runs on test_CT {
2239 /* MS -> SGSN: Attach Request IMSI
2240 * MS <- SGSN: Identity Request IMSI (optional)
2241 * MS -> SGSN: Identity Response IMSI (optional)
2242 * MS <- SGSN: Identity Request IMEI
2243 * MS -x SGSN: no response
2244 * MS <- SGSN: re-send: Identity Request IMEI 4x
2245 * MS <- SGSN: Attach Reject
2246 */
2247 var BSSGP_ConnHdlr vc_conn;
2248 f_init();
2249 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002250 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 +02002251 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002252 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002253}
2254
Alexander Couzens53f20562018-06-12 16:24:12 +02002255/* Attempt an attach, but loose the Identification Request (IMSI) */
2256private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2257 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002258 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002259
2260 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2261 g_pars.p_tmsi := 'c0000035'O;
2262
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002263 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 +02002264
2265 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002266 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002267 /* break */
2268 }
Harald Welte955aa942019-05-03 01:29:29 +02002269 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002270 /* ignore ID REQ IMSI */
2271 count_req := count_req + 1;
2272 repeat;
2273 }
Harald Welte955aa942019-05-03 01:29:29 +02002274 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002275 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002276 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002277 repeat;
2278 }
2279 }
2280 if (count_req != 5) {
2281 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002282 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002283 }
2284 setverdict(pass);
2285}
2286
2287testcase TC_attach_no_imsi_response() runs on test_CT {
2288 /* MS -> SGSN: Attach Request TMSI (unknown)
2289 * MS <- SGSN: Identity Request IMEI (optional)
2290 * MS -> SGSN: Identity Response IMEI (optional)
2291 * MS <- SGSN: Identity Request IMSI
2292 * MS -x SGSN: no response
2293 * MS <- SGSN: re-send: Identity Request IMSI 4x
2294 * MS <- SGSN: Attach Reject
2295 */
2296 var BSSGP_ConnHdlr vc_conn;
2297 f_init();
2298 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002299 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 +02002300 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002301 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002302}
2303
Alexander Couzenscf818962018-06-05 18:00:00 +02002304private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2305 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2306}
2307
2308testcase TC_attach_check_subscriber_list() runs on test_CT {
2309 /* MS <-> SGSN: Attach
2310 * VTY -> SGSN: Check if MS is in subscriber cache
2311 */
2312 var BSSGP_ConnHdlr vc_conn;
2313 var integer id := 34;
2314 var charstring imsi := hex2str(f_gen_imsi(id));
2315
2316 f_init();
2317 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002318 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002319 vc_conn.done;
2320
2321 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2322 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002323 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002324}
2325
Alexander Couzensf9858652018-06-07 16:14:53 +02002326private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2327 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002328 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002329
2330 /* unregister the old IMSI */
2331 f_bssgp_client_unregister(g_pars.imsi);
2332 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002333 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002334 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002335
2336 /* there is no auth */
2337 g_pars.net.expect_auth := false;
2338
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002339 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002340 f_gmm_auth();
2341 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002342 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002343 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002344 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002345 }
Harald Welte955aa942019-05-03 01:29:29 +02002346 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2347 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002348 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002349 setverdict(pass);
2350 }
2351 }
2352}
Alexander Couzens03d12242018-08-07 16:13:52 +02002353
2354private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2355
2356 f_TC_attach_closed_foreign(id);
2357 f_TC_attach_closed_imsi_added(id);
2358
2359}
2360
2361
Alexander Couzensf9858652018-06-07 16:14:53 +02002362testcase TC_attach_closed_add_vty() runs on test_CT {
2363 /* VTY-> SGSN: policy close
2364 * MS -> SGSN: Attach Request
2365 * MS <- SGSN: Identity Request IMSI
2366 * MS -> SGSN: Identity Response IMSI
2367 * MS <- SGSN: Attach Reject
2368 * VTY-> SGSN: policy imsi-acl add IMSI
2369 * MS -> SGSN: Attach Request
2370 * MS <- SGSN: Identity Request IMSI
2371 * MS -> SGSN: Identity Response IMSI
2372 * MS <- SGSN: Identity Request IMEI
2373 * MS -> SGSN: Identity Response IMEI
2374 * MS <- SGSN: Attach Accept
2375 */
2376 var BSSGP_ConnHdlr vc_conn;
2377 f_init();
2378 f_sleep(1.0);
2379 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2380 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002381 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2382 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002383 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002384 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002385 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002386 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002387}
2388
Alexander Couzens0085bd72018-06-12 19:08:44 +02002389/* Attempt an attach, but never answer a Attach Complete */
2390private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2391 var integer count_req := 0;
2392
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002393 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 +02002394 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002395 /* Expect SGSN to perform LU with HLR */
2396 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002397
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002398 timer T := 10.0;
2399 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002400 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002401 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002402 /* break */
2403 }
Harald Welte955aa942019-05-03 01:29:29 +02002404 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002405 /* ignore */
2406 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002407 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002408 repeat;
2409 }
2410 }
2411 if (count_req != 5) {
2412 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002413 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002414 }
2415 setverdict(pass);
2416}
2417
2418testcase TC_attach_check_complete_resend() runs on test_CT {
2419 /* MS -> SGSN: Attach Request IMSI
2420 * MS <- SGSN: Identity Request *
2421 * MS -> SGSN: Identity Response *
2422 * MS <- SGSN: Attach Complete 5x
2423 */
2424 var BSSGP_ConnHdlr vc_conn;
2425 f_init();
2426 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002427 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 +02002428 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002429 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002430}
2431
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002432friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002433 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002434 var PDU_DTAP_PS_MT mt;
2435 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002436
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002437 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002438 p_tmsi := g_pars.p_tmsi;
2439 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002440 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002441 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 +02002442 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002443 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2444 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2445 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002446 setverdict(pass);
2447 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002448 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2449 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2450 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002451 setverdict(pass);
2452 }
2453
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002454 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002455 setverdict(fail, "Unexpected RAU Reject");
2456 mtc.stop;
2457 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002458 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002459 setverdict(fail, "Unexpected RAU Reject");
2460 mtc.stop;
2461 }
2462
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002463 [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 +02002464 key_sts := ?)) {
2465 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2466 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002467 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002468 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002469 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002470 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2471 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002472 }
2473}
2474
Alexander Couzensbfda9212018-07-31 03:17:33 +02002475private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002476 /* first perform regular attach */
2477 f_TC_attach(id);
2478
2479 /* then send RAU */
2480 f_routing_area_update(g_pars.ra);
2481
2482 /* do another RAU */
2483 f_routing_area_update(g_pars.ra);
2484
2485 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2486}
2487
2488testcase TC_attach_rau_a_a() runs on test_CT {
2489 /* MS <-> SGSN: Successful Attach
2490 * MS -> SGSN: Routing Area Update Request
2491 * MS <- SGSN: Routing Area Update Accept
2492 * MS -> SGSN: Routing Area Update Request
2493 * MS <- SGSN: Routing Area Update Accept
2494 * MS -> SGSN: Detach (PowerOff)
2495 */
2496 var BSSGP_ConnHdlr vc_conn;
2497 f_init();
2498 f_sleep(1.0);
2499 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2500 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002501 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002502}
2503
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002504private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002505 f_TC_attach(id);
2506
2507 log("attach complete sending rau");
2508 f_routing_area_update(g_pars.ra, 0);
2509
2510 log("rau complete unregistering");
2511 f_bssgp_client_unregister(g_pars.imsi);
2512 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2513
2514 log("sending second RAU via different RA");
2515 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2516
2517 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2518}
2519
2520testcase TC_attach_rau_a_b() runs on test_CT {
2521 /* MS <-> SGSN: Successful Attach
2522 * MS -> SGSN: Routing Area _a_ Update Request
2523 * MS <- SGSN: Routing Area _a_ Update Accept
2524 * MS -> SGSN: Routing Area _b_ Update Request
2525 * MS <- SGSN: Routing Area _b_ Update Accept
2526 * MS -> SGSN: Detach (PowerOff)
2527 */
2528 var BSSGP_ConnHdlr vc_conn;
2529 f_init();
2530 f_sleep(1.0);
2531 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2532 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002533 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002534}
2535
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002536private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2537 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002538 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002539 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002540 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002541
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002542 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002543
2544 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002545 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002546 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2547 mtc.stop;
2548 }
Harald Welte955aa942019-05-03 01:29:29 +02002549 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002550 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002551 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002552 repeat;
2553 }
Harald Welte955aa942019-05-03 01:29:29 +02002554 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002555 /* send out a second GMM_Attach Request.
2556 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2557 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002558 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002559 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002560 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002561 }
2562 }
2563 f_sleep(1.0);
2564
2565 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2566 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002567 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002568 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002569 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002570 repeat;
2571 }
Harald Welte955aa942019-05-03 01:29:29 +02002572 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002573 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2574 mtc.stop;
2575 }
Harald Welte955aa942019-05-03 01:29:29 +02002576 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002577 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2578 mtc.stop;
2579 }
Harald Welte955aa942019-05-03 01:29:29 +02002580 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2581 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002582 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002583 setverdict(pass);
2584 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2585 }
2586 }
2587}
2588
2589testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2590 /* Testing if the SGSN ignore Attach Request with the exact same content */
2591 /* MS -> SGSN: Attach Request IMSI
2592 * MS <- SGSN: Identity Request IMSI (optional)
2593 * MS -> SGSN: Identity Response IMSI (optional)
2594 * MS <- SGSN: Identity Request IMEI
2595 * MS -> SGSN: Attach Request (2nd)
2596 * MS <- SGSN: Identity Response IMEI
2597 * MS <- SGSN: Attach Accept
2598 * MS -> SGSN: Attach Complete
2599 */
2600 var BSSGP_ConnHdlr vc_conn;
2601 f_init();
2602 f_sleep(1.0);
2603 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2604 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2605 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002606 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002607}
2608
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002609private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002610 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2611
2612 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2613
2614 /* send Attach Request */
2615 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2616 * 3G auth vectors */
2617 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2618 /* The thing is, if the solSACapability is 'omit', then the
2619 * revisionLevelIndicatior is at the wrong place! */
2620 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002621 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002622
2623 /* do the auth */
2624 var PDU_L3_MS_SGSN l3_mo;
2625 var PDU_L3_SGSN_MS l3_mt;
2626 var default di := activate(as_mm_identity());
2627
2628 var GSUP_IE auth_tuple;
2629 var template AuthenticationParameterAUTNTLV autn;
2630
2631 g_pars.vec := f_gen_auth_vec_3g();
2632 autn := {
2633 elementIdentifier := '28'O,
2634 lengthIndicator := lengthof(g_pars.vec.autn),
2635 autnValue := g_pars.vec.autn
2636 };
2637 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2638 g_pars.vec.sres,
2639 g_pars.vec.kc,
2640 g_pars.vec.ik,
2641 g_pars.vec.ck,
2642 g_pars.vec.autn,
2643 g_pars.vec.res));
2644 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2645 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2646 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2647
2648 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2649 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002650 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002651
2652 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002653 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002654
2655 /* wait for the GSUP resync request */
2656 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2657 g_pars.imsi,
2658 g_pars.vec.auts,
2659 g_pars.vec.rand));
2660
2661 /* generate new key material */
2662 g_pars.vec := f_gen_auth_vec_3g();
2663 autn := {
2664 elementIdentifier := '28'O,
2665 lengthIndicator := lengthof(g_pars.vec.autn),
2666 autnValue := g_pars.vec.autn
2667 };
2668
2669 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2670 g_pars.vec.sres,
2671 g_pars.vec.kc,
2672 g_pars.vec.ik,
2673 g_pars.vec.ck,
2674 g_pars.vec.autn,
2675 g_pars.vec.res));
2676 /* send new key material */
2677 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2678
2679 /* wait for the new Auth Request */
2680 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2681 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002682 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002683 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2684 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2685 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2686 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2687 valueField := substr(g_pars.vec.res, 0, 4)
2688 };
2689 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2690 elementIdentifier := '21'O,
2691 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2692 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2693 };
2694 l3_mo := valueof(auth_ciph_resp);
2695 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2696 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2697 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2698 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2699 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002700 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002701 deactivate(di);
2702
2703 /* Expect SGSN to perform LU with HLR */
2704 f_gmm_gsup_lu_isd();
2705
Harald Welte955aa942019-05-03 01:29:29 +02002706 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2707 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002708 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002709 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002710 setverdict(pass);
2711}
2712
2713testcase TC_attach_usim_resync() runs on test_CT {
2714 /* MS -> SGSN: Attach Request
2715 * MS <- SGSN: Identity Request IMSI
2716 * MS -> SGSN: Identity Response IMSI
2717 * MS <- SGSN: Identity Request IMEI
2718 * MS -> SGSN: Identity Response IMEI
2719 * HLR<- SGSN: SAI Request
2720 * HLR-> SGSN: SAI Response
2721 * MS <- SGSN: Auth Request
2722 * MS -> SGSN: Auth Failure (with AUTS)
2723 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2724 * HLR-> SGSN: SAI Response (new key material)
2725 * MS <- SGSN: Auth Request (new key material)
2726 * MS -> SGSN: Auth Response
2727 * MS <- SGSN: Attach Accept
2728 * MS -> SGSN: Attach Complete
2729 */
2730 var BSSGP_ConnHdlr vc_conn;
2731 f_init();
2732 f_sleep(1.0);
2733 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2734 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002735 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002736}
2737
Harald Weltea05b8072019-04-23 22:35:05 +02002738
2739/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2740private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2741 f_gmm_attach(false, false);
2742 f_sleep(1.0);
2743 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2744 /* try to detach to check if SGSN is still alive */
2745 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2746}
2747testcase TC_llc_null() runs on test_CT {
2748 var BSSGP_ConnHdlr vc_conn;
2749 f_init();
2750 f_sleep(1.0);
2751 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2752 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002753 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002754}
2755
Harald Welte645a1512019-04-23 23:18:23 +02002756/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2757private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2758 f_gmm_attach(false, false);
2759 f_sleep(1.0);
2760 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002761 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002762 setverdict(pass);
2763}
2764testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2765 var BSSGP_ConnHdlr vc_conn;
2766 f_init();
2767 f_sleep(1.0);
2768 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2769 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002770 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002771}
2772
2773/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2774private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2775 f_gmm_attach(false, false);
2776 f_sleep(1.0);
2777 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002778 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002779 setverdict(pass);
2780}
2781testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2782 var BSSGP_ConnHdlr vc_conn;
2783 f_init();
2784 f_sleep(1.0);
2785 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2786 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002787 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002788}
2789
Harald Welte2aaac1b2019-05-02 10:02:53 +02002790/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2791private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2792 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2793 var template (value) XID_Information xid;
2794 var template XID_Information xid_rx;
2795
2796 /* first perform regular attach */
2797 f_TC_attach(id);
2798 /* then activate PDP context */
2799 f_pdp_ctx_act(apars);
2800
2801 /* start MO XID */
2802 xid := { ts_XID_L3(''O) };
2803 xid_rx := { tr_XID_L3(''O) };
2804 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2805 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002806 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002807 [] as_xid(apars);
2808 }
2809 setverdict(pass);
2810}
2811testcase TC_xid_empty_l3() runs on test_CT {
2812 var BSSGP_ConnHdlr vc_conn;
2813 f_init();
2814 f_sleep(1.0);
2815 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2816 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002817 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002818}
2819
2820private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2821 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2822 var template (value) XID_Information xid;
2823 var template XID_Information xid_rx;
2824
2825 /* first perform regular attach */
2826 f_TC_attach(id);
2827 /* then activate PDP context */
2828 f_pdp_ctx_act(apars);
2829
2830 /* start MO XID */
2831 xid := { ts_XID_N201U(1234) };
2832 xid_rx := { tr_XID_N201U(1234) };
2833 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2834 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002835 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002836 [] as_xid(apars);
2837 }
2838 setverdict(pass);
2839}
2840testcase TC_xid_n201u() runs on test_CT {
2841 var BSSGP_ConnHdlr vc_conn;
2842 f_init();
2843 f_sleep(1.0);
2844 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2845 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002846 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002847}
2848
Alexander Couzens6bee0872019-05-11 01:48:50 +02002849private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2850 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2851
2852 /* first perform regular attach */
2853 f_TC_attach(id);
2854 /* then activate PDP context */
2855 f_pdp_ctx_act(apars);
2856 /* do a normal detach */
2857 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2858}
2859
2860testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2861 /* MS -> SGSN: Attach Request
2862 * MS <-> SGSN: [..]
2863 * MS -> SGSN: Attach Complete
2864 * MS -> SGSN: PDP Activate Request
2865 * MS <- SGSN: PDP Activate Accept
2866 * MS -> SGSN: GMM Detach Request
2867 * MS <- SGSN: GMM Detach Accept
2868 */
2869 var BSSGP_ConnHdlr vc_conn;
2870 f_init();
2871 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2872 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002873 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002874}
Harald Welte645a1512019-04-23 23:18:23 +02002875
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002876private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2877 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2878 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2879 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2880 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2881 var PDU_L3_SGSN_MS l3_mt;
2882
2883 f_send_l3(attach_req, 0);
2884
2885 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2886
2887 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2888 alt {
2889 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2890 setverdict(pass);
2891 }
2892 [] BSSGP[0].receive { repeat; }
2893 }
2894}
2895
2896/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2897 * See OS#3957 and OS#4245 for more information.
2898 */
2899testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2900 /*
2901 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2902 * MS <-- SGSN: Identity Request (IMEI)
2903 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2904 */
2905 var BSSGP_ConnHdlr vc_conn;
2906 f_init();
2907 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2908 vc_conn.done;
2909 f_cleanup();
2910}
2911
Harald Welte8e5932e2020-06-17 22:12:54 +02002912private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2913var PDU_BSSGP rx;
2914[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2915 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2916 mtc.stop;
2917 }
2918}
2919
2920/* SUSPEND, then DL traffic: should not pass + no paging expected */
2921private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2922 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2923 var default d;
2924
2925 /* first perform regular attach */
2926 f_TC_attach(id);
2927 /* then activate PDP context */
2928 f_pdp_ctx_act(apars);
2929 /* then transceive a downlink PDU */
2930 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2931
2932 /* now suspend GPRS */
2933 f_bssgp_suspend();
2934
2935 d := activate(as_nopaging_ps());
2936
2937 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2938 * nor any related paging requests */
2939 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2940
2941 deactivate(d);
2942}
2943testcase TC_suspend_nopaging() runs on test_CT {
2944 var BSSGP_ConnHdlr vc_conn;
2945 f_init();
2946 f_sleep(1.0);
2947 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
2948 vc_conn.done;
2949 f_cleanup();
2950}
2951
2952
2953/* SUSPEND, then RESUME: data expected to flow after explicit resume */
2954private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
2955 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2956 var OCT1 susp_ref;
2957 var default d;
2958
2959 /* first perform regular attach */
2960 f_TC_attach(id);
2961 /* then activate PDP context */
2962 f_pdp_ctx_act(apars);
2963 /* then transceive a downlink PDU */
2964 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2965
2966 /* now suspend GPRS */
2967 susp_ref := f_bssgp_suspend();
2968
2969 d := activate(as_nopaging_ps());
2970
2971 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2972 * nor any related paging requests */
2973 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2974
2975 deactivate(d);
2976
2977 /* resume GPRS */
2978 f_bssgp_resume(susp_ref);
2979
2980 /* now data should be flowing again */
2981 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2982}
2983testcase TC_suspend_resume() runs on test_CT {
2984 var BSSGP_ConnHdlr vc_conn;
2985 f_init();
2986 f_sleep(1.0);
2987 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
2988 vc_conn.done;
2989 f_cleanup();
2990}
2991
2992/* SUSPEND, then RAU: data expected to flow after implicit resume */
2993private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
2994 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2995 var default d;
2996
2997 /* first perform regular attach */
2998 f_TC_attach(id);
2999 /* then activate PDP context */
3000 f_pdp_ctx_act(apars);
3001 /* then transceive a downlink PDU */
3002 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3003
3004 /* now suspend GPRS */
3005 f_bssgp_suspend();
3006
3007 d := activate(as_nopaging_ps());
3008
3009 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3010 * nor any related paging requests */
3011 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3012
3013 deactivate(d);
3014
3015 /* perform RAU (implicit RESUME) */
3016 f_routing_area_update(g_pars.ra);
3017
3018 /* now data should be flowing again */
3019 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3020
3021}
3022testcase TC_suspend_rau() runs on test_CT {
3023 var BSSGP_ConnHdlr vc_conn;
3024 f_init();
3025 f_sleep(1.0);
3026 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3027 vc_conn.done;
3028 f_cleanup();
3029}
3030
3031
3032/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3033private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3034 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3035 var default d;
3036
3037 /* first perform regular attach */
3038 f_TC_attach(id);
3039 /* then activate PDP context */
3040 f_pdp_ctx_act(apars);
3041 /* then transceive a downlink PDU */
3042 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3043
3044 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3045 f_sleep(5.0);
3046
3047 /* now data should be flowing again, but with PS PAGING */
3048 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3049 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3050
3051 /* FIXME: simulate paging response */
3052 /* FIXME: verify PDU actually arrives only after paging response was successful */
3053
3054}
3055testcase TC_paging_ps() runs on test_CT {
3056 var BSSGP_ConnHdlr vc_conn;
3057 f_init();
3058 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3059 f_sleep(1.0);
3060 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3061 vc_conn.done;
3062 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3063 f_cleanup();
3064}
3065
3066
3067
3068
3069
Harald Welte5ac31492018-02-15 20:39:13 +01003070control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003071 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003072 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003073 execute( TC_attach_umts_aka_umts_res() );
3074 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003075 execute( TC_attach_auth_id_timeout() );
3076 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003077 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003078 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003079 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003080 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003081 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003082 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003083 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003084 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003085 execute( TC_attach_closed_add_vty(), 20.0 );
3086 execute( TC_attach_check_subscriber_list(), 20.0 );
3087 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003088 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003089 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3090 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3091 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3092 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003093 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003094 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003095 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003096 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003097 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003098 execute( TC_detach_unknown_nopoweroff() );
3099 execute( TC_detach_unknown_poweroff() );
3100 execute( TC_detach_nopoweroff() );
3101 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003102 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003103 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003104 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003105 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003106 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003107 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003108 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003109 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003110 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003111 execute( TC_attach_restart_ctr_echo() );
3112 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003113 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003114 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3115 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003116 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003117 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003118 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003119
Harald Welte2aaac1b2019-05-02 10:02:53 +02003120 execute( TC_xid_empty_l3() );
3121 execute( TC_xid_n201u() );
3122
Harald Weltea05b8072019-04-23 22:35:05 +02003123 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003124 execute( TC_llc_sabm_dm_llgmm() );
3125 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003126
Harald Welte8e5932e2020-06-17 22:12:54 +02003127 execute( TC_suspend_nopaging() );
3128 execute( TC_suspend_resume() );
3129 execute( TC_suspend_rau() );
3130 execute( TC_paging_ps() );
3131
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003132 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3133 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003134}
Harald Welte96a33b02018-02-04 10:36:22 +01003135
3136
3137
3138}