blob: 03c9d05b7d8f0a26644a73c25d5c151d0db0ee37 [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 Welte96a33b02018-02-04 10:36:22 +010014import from General_Types all;
15import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010016import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010017import from NS_Types all;
18import from NS_Emulation all;
19import from BSSGP_Types all;
20import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010021import from Osmocom_Gb_Types all;
22
23import from MobileL3_CommonIE_Types all;
24import from MobileL3_GMM_SM_Types all;
25import from MobileL3_Types all;
26import from L3_Templates all;
27import from L3_Common all;
28
29import from GSUP_Emulation all;
30import from GSUP_Types all;
31import from IPA_Emulation all;
32
Harald Welteeded9ad2018-02-17 20:57:34 +010033import from GTP_Emulation all;
34import from GTP_Templates all;
35import from GTP_CodecPort all;
36import from GTPC_Types all;
37import from GTPU_Types all;
38
Harald Weltea2526a82018-02-18 19:03:36 +010039import from LLC_Types all;
40import from LLC_Templates all;
41
42import from SNDCP_Types all;
43
Harald Weltebd194722018-02-16 22:11:08 +010044import from TELNETasp_PortType all;
45import from Osmocom_VTY_Functions all;
46
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010047import from GSM_RR_Types all;
48
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020049import from MobileL3_MM_Types all;
50
Harald Welteeded9ad2018-02-17 20:57:34 +010051
Harald Welte5ac31492018-02-15 20:39:13 +010052modulepar {
53 /* IP/port on which we run our internal GSUP/HLR emulation */
54 charstring mp_hlr_ip := "127.0.0.1";
55 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010056 charstring mp_ggsn_ip := "127.0.0.2";
Alexander Couzens2c12b242018-07-31 00:30:11 +020057
Alexander Couzensf3c1b412018-08-24 00:42:51 +020058 NSConfigurations mp_nsconfig := {
59 {
60 local_udp_port := 21010,
61 local_ip := "127.0.0.1",
62 remote_udp_port := 23000,
63 remote_ip := "127.0.0.1",
64 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020065 nsei := 96,
66 role_sgsn := false,
67 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020068 },
69 {
70 local_udp_port := 21011,
71 local_ip := "127.0.0.1",
72 remote_udp_port := 23000,
73 remote_ip := "127.0.0.1",
74 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020075 nsei := 97,
76 role_sgsn := false,
77 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020078 },
79 {
80 local_udp_port := 21012,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020085 nsei := 98,
86 role_sgsn := false,
87 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020089 };
Harald Welte5ac31492018-02-15 20:39:13 +010090};
91
92type record GbInstance {
93 NS_CT vc_NS,
94 BSSGP_CT vc_BSSGP,
95 BssgpConfig cfg
96};
Harald Welte96a33b02018-02-04 10:36:22 +010097
Harald Welte2fa771f2019-05-02 20:13:53 +020098const integer NUM_GB := 3;
99type record length(NUM_GB) of GbInstance GbInstances;
100type record length(NUM_GB) of NSConfiguration NSConfigurations;
101type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200102
Harald Welte96a33b02018-02-04 10:36:22 +0100103type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200104 var GbInstances g_gb;
Harald Welte96a33b02018-02-04 10:36:22 +0100105
Harald Welte5ac31492018-02-15 20:39:13 +0100106 var GSUP_Emulation_CT vc_GSUP;
107 var IPA_Emulation_CT vc_GSUP_IPA;
108 /* only to get events from IPA underneath GSUP */
109 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100110
Harald Welteeded9ad2018-02-17 20:57:34 +0100111 var GTP_Emulation_CT vc_GTP;
112
Harald Weltebd194722018-02-16 22:11:08 +0100113 port TELNETasp_PT SGSNVTY;
114
Harald Welte96a33b02018-02-04 10:36:22 +0100115 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200116 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100117};
118
Harald Welteeded9ad2018-02-17 20:57:34 +0100119type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100120 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100121 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200122 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100123}
124
125type record SGSN_ConnHdlrNetworkPars {
126 boolean expect_ptmsi,
127 boolean expect_auth,
128 boolean expect_ciph
129};
130
131type record BSSGP_ConnHdlrPars {
132 /* IMEI of the simulated ME */
133 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200134 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100135 hexstring imsi,
136 /* MSISDN of the simulated MS (probably unused) */
137 hexstring msisdn,
138 /* P-TMSI allocated to the simulated MS */
139 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100140 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100141 /* TLLI of the simulated MS */
142 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100143 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100144 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200145 BssgpCellIds bssgp_cell_id,
Harald Welte5ac31492018-02-15 20:39:13 +0100146 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100147 SGSN_ConnHdlrNetworkPars net,
148 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100149};
150
Alexander Couzens89508702018-07-31 04:16:10 +0200151private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200152 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200153 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
154
155 var RoutingAreaIdentificationV ret := {
156 mccDigit1 := mcc_mnc[0],
157 mccDigit2 := mcc_mnc[1],
158 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200159 mncDigit3 := mcc_mnc[3],
160 mncDigit1 := mcc_mnc[4],
161 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200162 lac := int2oct(cell_id.ra_id.lai.lac, 16),
163 rac := int2oct(cell_id.ra_id.rac, 8)
164 }
165 return ret;
166};
167
Alexander Couzens51114d12018-07-31 18:41:56 +0200168private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
169 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
170 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100171 /* connect lower end of BSSGP emulation with NS upper port */
172 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
173 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
174 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
175
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200176 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100177 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
178}
179
180private function f_init_gsup(charstring id) runs on test_CT {
181 id := id & "-GSUP";
182 var GsupOps ops := {
183 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
184 };
185
186 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
187 vc_GSUP := GSUP_Emulation_CT.create(id);
188
189 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
190 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
191 /* we use this hack to get events like ASP_IPA_EVENT_UP */
192 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
193
194 vc_GSUP.start(GSUP_Emulation.main(ops, id));
195 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
196
197 /* wait for incoming connection to GSUP port before proceeding */
198 timer T := 10.0;
199 T.start;
200 alt {
201 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
202 [] T.timeout {
203 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200204 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100205 }
206 }
207}
208
Harald Welteeded9ad2018-02-17 20:57:34 +0100209private function f_init_gtp(charstring id) runs on test_CT {
210 id := id & "-GTP";
211
212 var GtpEmulationCfg gtp_cfg := {
213 gtpc_bind_ip := mp_ggsn_ip,
214 gtpc_bind_port := GTP1C_PORT,
215 gtpu_bind_ip := mp_ggsn_ip,
216 gtpu_bind_port := GTP1U_PORT,
217 sgsn_role := false
218 };
219
220 vc_GTP := GTP_Emulation_CT.create(id);
221 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
222}
223
Harald Weltebd194722018-02-16 22:11:08 +0100224private function f_init_vty() runs on test_CT {
225 map(self:SGSNVTY, system:SGSNVTY);
226 f_vty_set_prompts(SGSNVTY);
227 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200228 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100229 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
230}
231
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200232private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
233 if (enable) {
234 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
235 } else {
236 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
237 }
238}
239
Harald Weltebd194722018-02-16 22:11:08 +0100240
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200241/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
242function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100243 if (g_initialized == true) {
244 return;
245 }
246 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100247 g_gb[0].cfg := {
248 nsei := 96,
249 bvci := 196,
250 cell_id := {
251 ra_id := {
252 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100253 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100254 rac := 0
255 },
256 cell_id := 20960
257 },
258 sgsn_role := false
259 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200260 g_gb[1].cfg := {
261 nsei := 97,
262 bvci := 210,
263 cell_id := {
264 ra_id := {
265 lai := {
266 mcc_mnc := mcc_mnc, lac := 13200},
267 rac := 0
268 },
269 cell_id := 20961
270 },
271 sgsn_role := false
272 };
273 g_gb[2].cfg := {
274 nsei := 98,
275 bvci := 220,
276 cell_id := {
277 ra_id := {
278 lai := {
279 mcc_mnc := mcc_mnc, lac := 13300},
280 rac := 0
281 },
282 cell_id := 20962
283 },
284 sgsn_role := false
285 };
Harald Welte96a33b02018-02-04 10:36:22 +0100286
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200287 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200288 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
289 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
290 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte5ac31492018-02-15 20:39:13 +0100291 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100292 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200293 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100294}
Harald Welte96a33b02018-02-04 10:36:22 +0100295
Harald Welte5ac31492018-02-15 20:39:13 +0100296type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
297
298/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200299function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100300 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100301runs on test_CT return BSSGP_ConnHdlr {
302 var BSSGP_ConnHdlr vc_conn;
303 var SGSN_ConnHdlrNetworkPars net_pars := {
304 expect_ptmsi := true,
305 expect_auth := true,
306 expect_ciph := false
307 };
308 var BSSGP_ConnHdlrPars pars := {
309 imei := f_gen_imei(imsi_suffix),
310 imsi := f_gen_imsi(imsi_suffix),
311 msisdn := f_gen_msisdn(imsi_suffix),
312 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100313 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100314 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100315 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100316 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200317 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Harald Welte5ac31492018-02-15 20:39:13 +0100318 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100319 net := net_pars,
320 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100321 };
322
323 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200324 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
325 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
326 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
327 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
328 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
329 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100330
331 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
332 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
333
Harald Welteeded9ad2018-02-17 20:57:34 +0100334 connect(vc_conn:GTP, vc_GTP:CLIENT);
335 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
336
Harald Welte5ac31492018-02-15 20:39:13 +0100337 vc_conn.start(f_handler_init(fn, id, pars));
338 return vc_conn;
339}
340
Harald Welte62e29582018-02-16 21:17:11 +0100341private altstep as_Tguard() runs on BSSGP_ConnHdlr {
342 [] g_Tguard.timeout {
343 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200344 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100345 }
346}
347
Harald Welte5ac31492018-02-15 20:39:13 +0100348/* first function called in every ConnHdlr */
349private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
350runs on BSSGP_ConnHdlr {
351 /* do some common stuff like setting up g_pars */
352 g_pars := pars;
353
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200354 llc := f_llc_create(false);
355
Harald Welte5ac31492018-02-15 20:39:13 +0100356 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200357 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100358 /* tell GSUP dispatcher to send this IMSI to us */
359 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100360 /* tell GTP dispatcher to send this IMSI to us */
361 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100362
Harald Welte62e29582018-02-16 21:17:11 +0100363 g_Tguard.start(pars.t_guard);
364 activate(as_Tguard());
365
Harald Welte5ac31492018-02-15 20:39:13 +0100366 /* call the user-supplied test case function */
367 fn.apply(id);
368 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100369}
370
371/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100372 * Detach without Attach
373 * SM procedures without attach / RAU
374 * ATTACH / RAU
375 ** with / without authentication
376 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100377 * re-transmissions of LLC frames
378 * PDP Context activation
379 ** with different GGSN config in SGSN VTY
380 ** with different PDP context type (v4/v6/v46)
381 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100382 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100383 */
384
385testcase TC_wait_ns_up() runs on test_CT {
386 f_init();
387 f_sleep(20.0);
388}
389
Harald Weltea05b8072019-04-23 22:35:05 +0200390function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
391 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
392 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
393}
394
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200395function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
396 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
397 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
398 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200399 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200400}
401
Harald Welteca362462019-05-02 20:11:21 +0200402altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100403 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welteca362462019-05-02 20:11:21 +0200404 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100405 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteca362462019-05-02 20:11:21 +0200406 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100407 repeat;
408 }
Harald Welteca362462019-05-02 20:11:21 +0200409 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100410 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welteca362462019-05-02 20:11:21 +0200411 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100412 repeat;
413 }
414}
Harald Welte96a33b02018-02-04 10:36:22 +0100415
Harald Welteca362462019-05-02 20:11:21 +0200416/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
417function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
418runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
419 var BssgpDecoded bd;
420 var PDU_L3_SGSN_MS l3_mt;
421 alt {
422 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(rx_tpl)) -> value bd {
423 l3_mt := bd.l3_mt;
424 }
425 }
426 return l3_mt;
427}
428
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200429/* perform GMM authentication (if expected).
430 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
431 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200432function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100433 var PDU_L3_MS_SGSN l3_mo;
434 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200435 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100436 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200437 var GSUP_IE auth_tuple;
438 var template AuthenticationParameterAUTNTLV autn;
439
440 if (umts_aka_challenge) {
441 g_pars.vec := f_gen_auth_vec_3g();
442 autn := {
443 elementIdentifier := '28'O,
444 lengthIndicator := lengthof(g_pars.vec.autn),
445 autnValue := g_pars.vec.autn
446 };
447
448 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
449 g_pars.vec.sres,
450 g_pars.vec.kc,
451 g_pars.vec.ik,
452 g_pars.vec.ck,
453 g_pars.vec.autn,
454 g_pars.vec.res));
455 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
456 } else {
457 g_pars.vec := f_gen_auth_vec_2g();
458 autn := omit;
459 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
460 g_pars.vec.sres,
461 g_pars.vec.kc));
462 log("GSUP sends only 2G auth tuple", auth_tuple);
463 }
Harald Welteca362462019-05-02 20:11:21 +0200464
Harald Welte5ac31492018-02-15 20:39:13 +0100465 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
466 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200467
468 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
469 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200470 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100471 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200472 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
473
474 if (umts_aka_challenge and not force_gsm_sres) {
475 /* set UMTS response instead */
476 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
477 valueField := substr(g_pars.vec.res, 0, 4)
478 };
479 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
480 elementIdentifier := '21'O,
481 lengthIndicator := lengthof(g_pars.vec.res) - 4,
482 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
483 };
484 }
485
486 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100487 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
488 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
489 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
490 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
491 }
Harald Welteca362462019-05-02 20:11:21 +0200492 f_send_l3_gmm_llc(l3_mo, gb_idx);
Harald Welte76dee092018-02-16 22:12:59 +0100493 } else {
494 /* wait for identity procedure */
495 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100496 }
Harald Welte76dee092018-02-16 22:12:59 +0100497
Harald Welte5ac31492018-02-15 20:39:13 +0100498 deactivate(di);
499}
500
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200501function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100502 g_pars.p_tmsi := p_tmsi;
503 /* update TLLI */
504 g_pars.tlli_old := g_pars.tlli;
505 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200506 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100507}
508
Harald Welte04683d02018-02-16 22:43:45 +0100509function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
510 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100511 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200512 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100513 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200514 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200515 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100516 }
Harald Welte04683d02018-02-16 22:43:45 +0100517 g_pars.ra := aa.routingAreaIdentification;
518 if (ispresent(aa.allocatedPTMSI)) {
519 if (not g_pars.net.expect_ptmsi) {
520 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200521 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100522 }
Harald Weltef70997d2018-02-17 10:11:19 +0100523 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100524 }
525 if (ispresent(aa.msIdentity)) {
526 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200527 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100528 }
529 /* P-TMSI.sig */
530 if (ispresent(aa.ptmsiSignature)) {
531 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
532 }
533 /* updateTimer */
534 // aa.readyTimer
535 /* T3302, T3319, T3323, T3312_ext, T3324 */
536}
537
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200538function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100539 /* mandatory IE */
540 g_pars.ra := ra.routingAreaId;
541 if (ispresent(ra.allocatedPTMSI)) {
542 if (not g_pars.net.expect_ptmsi) {
543 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200544 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100545 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200546 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100547 }
548 if (ispresent(ra.msIdentity)) {
549 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200550 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100551 }
552 /* P-TMSI.sig */
553 if (ispresent(ra.ptmsiSignature)) {
554 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
555 }
556 /* updateTimer */
557 // aa.readyTimer
558 /* T3302, T3319, T3323, T3312_ext, T3324 */
559}
560
561
Harald Welte5a4fa042018-02-16 20:59:21 +0100562function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
563 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
564}
565
Harald Welte23178c52018-02-17 09:36:33 +0100566/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100567private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100568 if (ispresent(g_pars.p_tmsi)) {
569 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
570 } else {
571 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
572 }
573}
574
Harald Welte311ec272018-02-17 09:40:03 +0100575private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100576 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100577 /* Expect MSC to perform LU with HLR */
578 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100579 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
580 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
581 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100582 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
583 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
584}
585
Harald Welteca362462019-05-02 20:11:21 +0200586friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100587 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200588 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 +0200589 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100590
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200591 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
592 * 3G auth vectors */
593 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
594 /* The thing is, if the solSACapability is 'omit', then the
595 * revisionLevelIndicatior is at the wrong place! */
596 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
597
Harald Welteca362462019-05-02 20:11:21 +0200598 f_send_l3_gmm_llc(attach_req, gb_idx);
599 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200600 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100601 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100602
Harald Welteca362462019-05-02 20:11:21 +0200603 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
604 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
605
Harald Welte04683d02018-02-16 22:43:45 +0100606 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welteca362462019-05-02 20:11:21 +0200607 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL, gb_idx);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200608}
609
610private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
611 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100612 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100613}
614
615testcase TC_attach() runs on test_CT {
616 var BSSGP_ConnHdlr vc_conn;
617 f_init();
618 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200619 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100620 vc_conn.done;
621}
622
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100623testcase TC_attach_mnc3() runs on test_CT {
624 var BSSGP_ConnHdlr vc_conn;
625 f_init('023042'H);
626 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200627 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100628 vc_conn.done;
629}
630
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200631private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
632 f_gmm_attach(true, false);
633 setverdict(pass);
634}
635testcase TC_attach_umts_aka_umts_res() runs on test_CT {
636 var BSSGP_ConnHdlr vc_conn;
637 f_init();
638 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200639 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200640 vc_conn.done;
641}
642
643private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
644 f_gmm_attach(true, true);
645 setverdict(pass);
646}
647testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
648 var BSSGP_ConnHdlr vc_conn;
649 f_init();
650 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200651 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200652 vc_conn.done;
653}
654
Harald Welte5b7c8122018-02-16 21:48:17 +0100655/* MS never responds to ID REQ, expect ATTACH REJECT */
656private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100657 var RoutingAreaIdentificationV old_ra := f_random_RAI();
658
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200659 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100660 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200661 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100662 /* don't send ID Response */
663 repeat;
664 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200665 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100666 setverdict(pass);
667 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200668 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100669 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200670 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100671 }
672 }
673}
674testcase TC_attach_auth_id_timeout() runs on test_CT {
675 var BSSGP_ConnHdlr vc_conn;
676 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200677 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 +0100678 vc_conn.done;
679}
680
681/* HLR never responds to SAI REQ, expect ATTACH REJECT */
682private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100683 var RoutingAreaIdentificationV old_ra := f_random_RAI();
684
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200685 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100686 alt {
687 [] as_mm_identity();
688 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
689 }
690 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200691 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100692 setverdict(pass);
693}
694testcase TC_attach_auth_sai_timeout() runs on test_CT {
695 var BSSGP_ConnHdlr vc_conn;
696 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200697 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100698 vc_conn.done;
699}
700
Harald Weltefe253882018-02-17 09:25:00 +0100701/* HLR rejects SAI, expect ATTACH REJECT */
702private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100703 var RoutingAreaIdentificationV old_ra := f_random_RAI();
704
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200705 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100706 alt {
707 [] as_mm_identity();
708 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
709 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
710 }
711 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200712 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100713 setverdict(pass);
714}
715testcase TC_attach_auth_sai_reject() runs on test_CT {
716 var BSSGP_ConnHdlr vc_conn;
717 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200718 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100719 vc_conn.done;
720}
721
Harald Welte5b7c8122018-02-16 21:48:17 +0100722/* HLR never responds to UL REQ, expect ATTACH REJECT */
723private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100724 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100725 var RoutingAreaIdentificationV old_ra := f_random_RAI();
726
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200727 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100728 f_gmm_auth();
729 /* Expect MSC to perform LU with HLR */
730 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
731 /* Never follow-up with ISD_REQ or UL_RES */
732 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200733 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100734 setverdict(pass);
735 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200736 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100737 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100738 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200739 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100740 }
741 }
742}
743testcase TC_attach_gsup_lu_timeout() runs on test_CT {
744 var BSSGP_ConnHdlr vc_conn;
745 f_init();
746 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200747 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100748 vc_conn.done;
749}
750
Harald Welteb7c14e92018-02-17 09:29:16 +0100751/* HLR rejects UL REQ, expect ATTACH REJECT */
752private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
753 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100754 var RoutingAreaIdentificationV old_ra := f_random_RAI();
755
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200756 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100757 f_gmm_auth();
758 /* Expect MSC to perform LU with HLR */
759 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
760 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
761 }
762 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200763 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100764 setverdict(pass);
765 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200766 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100767 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
768 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200769 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100770 }
771 }
772}
773testcase TC_attach_gsup_lu_reject() runs on test_CT {
774 var BSSGP_ConnHdlr vc_conn;
775 f_init();
776 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200777 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100778 vc_conn.done;
779}
780
781
Harald Welte3823e2e2018-02-16 21:53:48 +0100782/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
783private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100784 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100785 var RoutingAreaIdentificationV old_ra := f_random_RAI();
786
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200787 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100788 f_gmm_auth();
789 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100790 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100791
Alexander Couzens0e510e62018-07-28 23:06:00 +0200792 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100793 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
794 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200795 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100796 setverdict(pass);
797}
Harald Welte3823e2e2018-02-16 21:53:48 +0100798testcase TC_attach_combined() runs on test_CT {
799 var BSSGP_ConnHdlr vc_conn;
800 f_init();
801 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200802 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100803 vc_conn.done;
804}
805
Harald Welte76dee092018-02-16 22:12:59 +0100806/* Attempt of GPRS ATTACH in 'accept all' mode */
807private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100808 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100809 var RoutingAreaIdentificationV old_ra := f_random_RAI();
810
811 g_pars.net.expect_auth := false;
812
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200813 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100814 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200815 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100816 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
817 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200818 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100819 setverdict(pass);
820}
821testcase TC_attach_accept_all() runs on test_CT {
822 var BSSGP_ConnHdlr vc_conn;
823 f_init();
824 f_sleep(1.0);
825 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200826 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100827 vc_conn.done;
828}
Harald Welte5b7c8122018-02-16 21:48:17 +0100829
Harald Welteb2124b22018-02-16 22:26:56 +0100830/* Attempt of GPRS ATTACH in 'accept all' mode */
831private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100832 var RoutingAreaIdentificationV old_ra := f_random_RAI();
833
834 /* Simulate a foreign IMSI */
835 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200836 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100837
838 g_pars.net.expect_auth := false;
839
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200840 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100841 alt {
842 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200843 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100844 setverdict(pass);
845 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200846 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100847 setverdict(pass);
848 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200849 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200850 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200851 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200852 }
Harald Welteb2124b22018-02-16 22:26:56 +0100853 }
854}
855testcase TC_attach_closed() runs on test_CT {
856 var BSSGP_ConnHdlr vc_conn;
857 f_init();
858 f_sleep(1.0);
859 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
860 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200861 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100862 vc_conn.done;
863 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200864 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100865 vc_conn.done;
866}
867
Harald Welte04683d02018-02-16 22:43:45 +0100868/* Routing Area Update from Unknown TLLI -> REJECT */
869private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100870 var RoutingAreaIdentificationV old_ra := f_random_RAI();
871
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200872 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +0100873 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200874 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100875 setverdict(pass);
876 }
877 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200878 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100879 }
880}
881testcase TC_rau_unknown() runs on test_CT {
882 var BSSGP_ConnHdlr vc_conn;
883 f_init();
884 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200885 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100886 vc_conn.done;
887}
888
Harald Welte91636de2018-02-17 10:16:14 +0100889private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
890 var BssgpDecoded bd;
891
892 /* first perform regular attach */
893 f_TC_attach(id);
894
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200895 f_routing_area_update(g_pars.ra);
896
Harald Welte91636de2018-02-17 10:16:14 +0100897}
898testcase TC_attach_rau() runs on test_CT {
899 var BSSGP_ConnHdlr vc_conn;
900 f_init();
901 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200902 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100903 vc_conn.done;
904}
Harald Welte04683d02018-02-16 22:43:45 +0100905
Harald Welte6abb9fe2018-02-17 15:24:48 +0100906/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200907function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100908 var BssgpDecoded bd;
909 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200910 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100911 if (expect_purge) {
912 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
913 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
914 }
915 T.start;
916 alt {
917 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
918 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200919 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100920 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200921 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100922 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +0200923 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200924 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100925 /* TODO: check if any PDP contexts are deactivated on network side? */
926 }
927 [power_off] T.timeout {
928 setverdict(pass);
929 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200930 [not power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100931 g_pars.ra := omit;
932 setverdict(pass);
933 /* TODO: check if any PDP contexts are deactivated on network side? */
934 }
Alexander Couzens4630e742019-05-11 01:50:10 +0200935 [] BSSGP[bssgp_index].receive(tr_BD_L3_MT(?)) -> value bd {
936 if (power_off) {
937 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
938 } else {
939 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
940 }
941 mtc.stop;
942 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200943 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100944 }
945}
946
947/* IMSI DETACH (non-power-off) for unknown TLLI */
948private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
949 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
950}
951testcase TC_detach_unknown_nopoweroff() runs on test_CT {
952 var BSSGP_ConnHdlr vc_conn;
953 f_init();
954 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200955 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100956 vc_conn.done;
957}
958
959/* IMSI DETACH (power-off) for unknown TLLI */
960private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
961 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
962}
963testcase TC_detach_unknown_poweroff() runs on test_CT {
964 var BSSGP_ConnHdlr vc_conn;
965 f_init();
966 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200967 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100968 vc_conn.done;
969}
970
971/* IMSI DETACH (non-power-off) for known TLLI */
972private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
973 /* first perform regular attach */
974 f_TC_attach(id);
975
976 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
977}
978testcase TC_detach_nopoweroff() runs on test_CT {
979 var BSSGP_ConnHdlr vc_conn;
980 f_init();
981 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200982 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100983 vc_conn.done;
984}
985
986/* IMSI DETACH (power-off) for known TLLI */
987private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
988 /* first perform regular attach */
989 f_TC_attach(id);
990
991 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
992}
993testcase TC_detach_poweroff() runs on test_CT {
994 var BSSGP_ConnHdlr vc_conn;
995 f_init();
996 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200997 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100998 vc_conn.done;
999}
1000
Harald Welteeded9ad2018-02-17 20:57:34 +01001001type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001002 BIT3 tid, /* L3 Transaction ID */
1003 BIT4 nsapi, /* SNDCP NSAPI */
1004 BIT4 sapi, /* LLC SAPI */
1005 QoSV qos, /* QoS parameters */
1006 PDPAddressV addr, /* IP address */
1007 octetstring apn optional, /* APN name */
1008 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1009 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001010 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001011 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001012
Harald Welte822f9102018-02-18 20:39:06 +01001013 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1014 OCT4 ggsn_tei_u, /* GGSN TEI User */
1015 octetstring ggsn_ip_c, /* GGSN IP Control */
1016 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001017 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001018
Harald Welte822f9102018-02-18 20:39:06 +01001019 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1020 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1021 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1022 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001023};
1024
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001025
1026private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1027 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1028 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1029 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1030 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1031 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1032 f_gtp_register_teid(apars.ggsn_tei_c);
1033 f_gtp_register_teid(apars.ggsn_tei_u);
1034}
1035
Harald Weltef7191672019-05-02 20:37:23 +02001036function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1037runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001038 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1039 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001040 var template Recovery_gtpc recovery := omit;
1041
1042 if (send_recovery) {
1043 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1044 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001045
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001046 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001047 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001048 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1049 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1050 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1051 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1052 apars.sgsn_tei_c, apars.gtp_resp_cause,
1053 apars.ggsn_tei_c, apars.ggsn_tei_u,
1054 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001055 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1056 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001057 }
1058 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001059 [exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001060 setverdict(pass);
1061 }
Harald Weltef7191672019-05-02 20:37:23 +02001062 [exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001063 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001064 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001065 }
Harald Weltef7191672019-05-02 20:37:23 +02001066 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001067 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001068 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001069 }
Harald Weltef7191672019-05-02 20:37:23 +02001070 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
1071 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1072 mtc.stop;
1073 }
1074 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001075 setverdict(pass);
1076 }
Harald Weltef7191672019-05-02 20:37:23 +02001077 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001078 }
1079}
1080
Harald Weltef7191672019-05-02 20:37:23 +02001081function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1082runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001083 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1084 var Gtp1cUnitdata g_ud;
1085
Harald Weltef7191672019-05-02 20:37:23 +02001086 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001087 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1088 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001089 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001090 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1091 }
1092 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001093 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001094 setverdict(pass);
1095 }
Harald Weltef7191672019-05-02 20:37:23 +02001096 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001097 }
1098}
1099
Harald Weltef7191672019-05-02 20:37:23 +02001100function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1101runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001102 var Gtp1cUnitdata g_ud;
1103 var integer seq_nr := 23;
1104 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1105
Harald Weltef7191672019-05-02 20:37:23 +02001106 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001107 if (error_ind) {
1108 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1109 } else {
1110 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1111 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001112
1113 timer T := 5.0;
1114 T.start;
1115
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001116 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001117 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
1118 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001119 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001120 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1121 repeat;
1122 }
1123 [] T.timeout {
1124 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1125 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001126 }
1127}
1128
Harald Welte6f203162018-02-18 22:04:55 +01001129
Harald Welteeded9ad2018-02-17 20:57:34 +01001130/* Table 10.5.156/3GPP TS 24.008 */
1131template (value) QoSV t_QosDefault := {
1132 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1133 delayClass := '100'B, /* best effort */
1134 spare1 := '00'B,
1135 precedenceClass := '010'B, /* normal */
1136 spare2 := '0'B,
1137 peakThroughput := '0000'B, /* subscribed */
1138 meanThroughput := '00000'B, /* subscribed */
1139 spare3 := '000'B,
1140 deliverErroneusSDU := omit,
1141 deliveryOrder := omit,
1142 trafficClass := omit,
1143 maxSDUSize := omit,
1144 maxBitrateUplink := omit,
1145 maxBitrateDownlink := omit,
1146 sduErrorRatio := omit,
1147 residualBER := omit,
1148 trafficHandlingPriority := omit,
1149 transferDelay := omit,
1150 guaranteedBitRateUplink := omit,
1151 guaranteedBitRateDownlink := omit,
1152 sourceStatisticsDescriptor := omit,
1153 signallingIndication := omit,
1154 spare4 := omit,
1155 maxBitrateDownlinkExt := omit,
1156 guaranteedBitRateDownlinkExt := omit,
1157 maxBitrateUplinkExt := omit,
1158 guaranteedBitRateUplinkExt := omit,
1159 maxBitrateDownlinkExt2 := omit,
1160 guaranteedBitRateDownlinkExt2 := omit,
1161 maxBitrateUplinkExt2 := omit,
1162 guaranteedBitRateUplinkExt2 := omit
1163}
1164
1165/* 10.5.6.4 / 3GPP TS 24.008 */
1166template (value) PDPAddressV t_AddrIPv4dyn := {
1167 pdpTypeOrg := '0001'B, /* IETF */
1168 spare := '0000'B,
1169 pdpTypeNum := '21'O, /* IPv4 */
1170 addressInfo := omit
1171}
1172template (value) PDPAddressV t_AddrIPv6dyn := {
1173 pdpTypeOrg := '0001'B, /* IETF */
1174 spare := '0000'B,
1175 pdpTypeNum := '53'O, /* IPv6 */
1176 addressInfo := omit
1177}
1178
Harald Welte37692d82018-02-18 15:21:34 +01001179template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001180 tid := '000'B,
1181 nsapi := '0101'B, /* < 5 are reserved */
1182 sapi := '0011'B, /* 3/5/9/11 */
1183 qos := t_QosDefault,
1184 addr := t_AddrIPv4dyn,
1185 apn := omit,
1186 pco := omit,
1187 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001188 gtp_resp_cause := int2oct(128, 1),
1189 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001190
1191 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001192 ggsn_tei_c := f_rnd_octstring(4),
1193 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001194 ggsn_ip_c := f_inet_addr(ggsn_ip),
1195 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001196 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001197
Harald Welteeded9ad2018-02-17 20:57:34 +01001198 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001199 sgsn_tei_u := omit,
1200 sgsn_ip_c := omit,
1201 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001202}
1203
Harald Welte37692d82018-02-18 15:21:34 +01001204template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1205 connId := 1,
1206 remName := f_inet_ntoa(ip),
1207 remPort := GTP1U_PORT
1208}
1209
1210template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1211 connId := 1,
1212 remName := f_inet_ntoa(ip),
1213 remPort := GTP1C_PORT
1214}
1215
1216private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1217 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1218 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1219}
1220
Harald Weltef7191672019-05-02 20:37:23 +02001221private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
1222 [] BSSGP[gb_idx].receive(tr_BD_LLC(tr_LLC_XID_MT_CMD(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001223 repeat;
1224 }
1225}
1226
1227template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1228 pDU_SN_UNITDATA := {
1229 nsapi := nsapi,
1230 moreBit := ?,
1231 snPduType := '1'B,
1232 firstSegmentIndicator := ?,
1233 spareBit := ?,
1234 pcomp := ?,
1235 dcomp := ?,
1236 npduNumber := ?,
1237 segmentNumber := ?,
1238 npduNumberContinued := ?,
1239 dataSegmentSnUnitdataPdu := payload
1240 }
1241}
1242
1243/* simple case: single segment, no compression */
1244template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1245 pDU_SN_UNITDATA := {
1246 nsapi := nsapi,
1247 moreBit := '0'B,
1248 snPduType := '1'B,
1249 firstSegmentIndicator := '1'B,
1250 spareBit := '0'B,
1251 pcomp := '0000'B,
1252 dcomp := '0000'B,
1253 npduNumber := '0000'B,
1254 segmentNumber := '0000'B,
1255 npduNumberContinued := '00'O,
1256 dataSegmentSnUnitdataPdu := payload
1257 }
1258}
1259
1260/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001261private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1262runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001263 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1264 f_gtpu_send(apars, payload);
1265 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1266 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001267 [] as_xid(apars, gb_idx);
1268 [] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001269 }
1270}
1271
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001272/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001273private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1274runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001275 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1276 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1277 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001278 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001279 /* Expect PDU via GTP from SGSN on simulated GGSN */
1280 alt {
1281 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1282 }
1283}
1284
Harald Welteeded9ad2018-02-17 20:57:34 +01001285private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001286 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001287
1288 /* first perform regular attach */
1289 f_TC_attach(id);
1290
1291 f_pdp_ctx_act(apars);
1292}
1293testcase TC_attach_pdp_act() runs on test_CT {
1294 var BSSGP_ConnHdlr vc_conn;
1295 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001296 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001297 vc_conn.done;
1298}
Harald Welteb2124b22018-02-16 22:26:56 +01001299
Harald Welte835b15f2018-02-18 14:39:11 +01001300/* PDP Context activation for not-attached subscriber; expect fail */
1301private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001302 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001303 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001304 apars.apn, apars.pco));
1305 alt {
1306 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001307 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001308 setverdict(pass);
1309 }
1310 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1311 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001312 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001313 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001314 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001315 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001316 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001317 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001318 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001319 }
1320}
1321testcase TC_pdp_act_unattached() runs on test_CT {
1322 var BSSGP_ConnHdlr vc_conn;
1323 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001324 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001325 vc_conn.done;
1326}
1327
Harald Welte37692d82018-02-18 15:21:34 +01001328/* ATTACH + PDP CTX ACT + user plane traffic */
1329private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1330 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1331
1332 /* first perform regular attach */
1333 f_TC_attach(id);
1334 /* then activate PDP context */
1335 f_pdp_ctx_act(apars);
1336 /* then transceive a downlink PDU */
1337 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1338 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1339}
1340testcase TC_attach_pdp_act_user() runs on test_CT {
1341 var BSSGP_ConnHdlr vc_conn;
1342 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001343 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001344 vc_conn.done;
1345}
1346
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001347/* ATTACH + PDP CTX ACT; reject from GGSN */
1348private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1349 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1350
1351 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1352 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1353
1354 /* first perform regular attach */
1355 f_TC_attach(id);
1356 /* then activate PDP context */
1357 f_pdp_ctx_act(apars);
1358}
1359testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1360 var BSSGP_ConnHdlr vc_conn;
1361 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001362 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001363 vc_conn.done;
1364}
Harald Welte835b15f2018-02-18 14:39:11 +01001365
Harald Welte6f203162018-02-18 22:04:55 +01001366/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1367private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1368 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1369
1370 /* first perform regular attach */
1371 f_TC_attach(id);
1372 /* then activate PDP context */
1373 f_pdp_ctx_act(apars);
1374 /* then transceive a downlink PDU */
1375 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1376 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1377
1378 f_pdp_ctx_deact_mo(apars, '00'O);
1379}
1380testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1381 var BSSGP_ConnHdlr vc_conn;
1382 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001383 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 +01001384 vc_conn.done;
1385}
1386
Harald Welte57b9b7f2018-02-18 22:28:13 +01001387/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1388private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1389 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1390
1391 /* first perform regular attach */
1392 f_TC_attach(id);
1393 /* then activate PDP context */
1394 f_pdp_ctx_act(apars);
1395 /* then transceive a downlink PDU */
1396 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1397 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1398
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001399 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001400}
1401testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1402 var BSSGP_ConnHdlr vc_conn;
1403 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001404 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 +01001405 vc_conn.done;
1406}
1407
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001408/* ATTACH + ATTACH (2nd) */
1409private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1410 g_pars.t_guard := 5.0;
1411
1412 /* first perform regular attach */
1413 f_TC_attach(id);
1414
1415 /* second to perform regular attach */
1416 f_TC_attach(id);
1417}
1418
1419
1420testcase TC_attach_second_attempt() runs on test_CT {
1421 var BSSGP_ConnHdlr vc_conn;
1422 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001423 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001424 vc_conn.done;
1425}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001426
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001427private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001428 var Gtp1cUnitdata g_ud;
1429 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1430
1431 /* first perform regular attach */
1432 f_TC_attach(id);
1433 /* Activate a pdp context against the GGSN */
1434 f_pdp_ctx_act(apars);
1435 /* Wait to receive first echo request and send initial Restart counter */
1436 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1437 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1438 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1439 }
1440 /* Wait to receive second echo request and send incremented Restart
1441 counter. This will fake a restarted GGSN, and pdp ctx allocated
1442 should be released by SGSN */
1443 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1444 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1445 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1446 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1447 }
1448 var OCT1 cause_network_failure := int2oct(38, 1)
1449 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001450 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001451 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001452 setverdict(pass);
1453 }
1454 [] as_xid(apars);
1455 }
1456 setverdict(pass);
1457}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001458/* ATTACH + trigger Recovery procedure through EchoResp */
1459testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001460 var BSSGP_ConnHdlr vc_conn;
1461 g_use_echo := true
1462 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001463 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 +02001464 vc_conn.done;
1465 g_use_echo := false
1466}
1467
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001468private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1469 var Gtp1cUnitdata g_ud;
1470 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1471 var integer seq_nr := 23;
1472 var GtpPeer peer;
1473 /* first perform regular attach */
1474 f_TC_attach(id);
1475
1476 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1477 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1478 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1479 f_pdp_ctx_act(apars, true);
1480
1481 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1482/* received. */
1483 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1484
1485 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1486 would be great to have an active pdp context here before triggering
1487 Recovery, and making sure the the DEACT request is sent by the SGSN.
1488 */
1489
1490 /* Activate a pdp context against the GGSN, send incremented Recovery
1491 IE. This should trigger the recovery path, but still this specific
1492 CTX activation should work. */
1493 apars.exp_rej_cause := omit; /* default value for tests */
1494 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1495 f_pdp_ctx_act(apars, true);
1496
1497 setverdict(pass);
1498}
1499/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1500testcase TC_attach_restart_ctr_create() runs on test_CT {
1501 var BSSGP_ConnHdlr vc_conn;
1502 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001503 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 +02001504 vc_conn.done;
1505}
1506
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001507/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1508private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1509 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1510 var integer seq_nr := 23;
1511 var GtpPeer peer;
1512 var integer i;
1513
1514 /* first perform regular attach */
1515 f_TC_attach(id);
1516 /* then activate PDP context */
1517 f_pdp_ctx_act(apars);
1518
Alexander Couzens0e510e62018-07-28 23:06:00 +02001519 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001520 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1521 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1522
1523 for (i := 0; i < 5; i := i+1) {
1524 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001525 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001526 [] as_xid(apars);
1527 }
1528 }
1529
1530 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1531
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001532 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001533 setverdict(pass);
1534}
1535testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1536 var BSSGP_ConnHdlr vc_conn;
1537 f_init();
1538 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001539 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 +02001540 vc_conn.done;
1541}
1542
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001543/* ATTACH + PDP CTX ACT dropped + retrans */
1544private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1545 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1546 var Gtp1cUnitdata g_ud_first, g_ud_second;
1547 /* first perform regular attach */
1548 f_TC_attach(id);
1549
1550 /* then activate PDP context on the Gb side */
1551 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1552 apars.apn, apars.pco), 0);
1553
1554 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1555 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1556 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1557 if (g_ud_first != g_ud_second) {
1558 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1559 mtc.stop;
1560 }
1561 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1562 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1563 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1564 apars.sgsn_tei_c, apars.gtp_resp_cause,
1565 apars.ggsn_tei_c, apars.ggsn_tei_u,
1566 apars.nsapi,
1567 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1568 omit, omit));
1569 }
1570 BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {}
1571
1572 /* Now the same with Deact */
1573 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1574 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1575 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1576 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1577 if (g_ud_first != g_ud_second) {
1578 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1579 mtc.stop;
1580 }
1581 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1582 BSSGP[0].clear;
1583 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1584 }
1585 alt {
1586 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
1587 setverdict(pass);
1588 }
1589 [] as_xid(apars, 0);
1590 }
1591
1592 setverdict(pass);
1593}
1594testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1595 var BSSGP_ConnHdlr vc_conn;
1596 f_init();
1597 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1598 vc_conn.done;
1599}
1600
1601/* Test that SGSN GTP response retransmit queue works fine */
1602private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1603 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1604 var integer seq_nr := 23;
1605 var Gtp1cUnitdata g_ud_first, g_ud_second;
1606 var template Gtp1cUnitdata g_delete_req;
1607 /* first perform regular attach + PDP context act */
1608 f_TC_attach(id);
1609 f_pdp_ctx_act(apars);
1610
1611 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1612 BSSGP[0].clear;
1613 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1614 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1615 GTP.send(g_delete_req);
1616 alt {
1617 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
1618 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1619 }
1620 [] as_xid(apars, 0);
1621 }
1622 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1623 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1624 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1625 mtc.stop;
1626 }
1627 };
1628
1629 /* Send duplicate DeleteCtxReq */
1630 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1631 GTP.send(g_delete_req);
1632 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1633 if (g_ud_first != g_ud_second) {
1634 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1635 mtc.stop;
1636 }
1637 }
1638
1639 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1640 * is handled differently by SGSN (expect "non-existent" cause) */
1641 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1642 GTP.send(g_delete_req);
1643 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1644 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1645 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1646 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1647 mtc.stop;
1648 }
1649 }
1650
1651 setverdict(pass);
1652}
1653testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1654 var BSSGP_ConnHdlr vc_conn;
1655 f_init();
1656 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1657 vc_conn.done;
1658}
1659
Alexander Couzens5e307b42018-05-22 18:12:20 +02001660private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1661 /* MS: perform regular attach */
1662 f_TC_attach(id);
1663
1664 /* HLR: cancel the location request */
1665 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1666 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001667
1668 /* ensure no Detach Request got received */
1669 timer T := 5.0;
1670 T.start;
1671 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001672 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001673 T.stop;
1674 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001675 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001676 }
1677 [] T.timeout {
1678 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001679 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001680 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001681 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001682 repeat;
1683 }
1684 }
1685}
1686
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001687/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1688private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1689 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1690
1691 /* first perform regular attach */
1692 f_TC_attach(id);
1693 /* then activate PDP context */
1694 f_pdp_ctx_act(apars);
1695 /* then transceive a downlink PDU */
1696 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1697
1698 /* Send Error indication as response from upload PDU and expect deact towards MS */
1699 f_pdp_ctx_deact_mt(apars, true);
1700}
1701testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1702 var BSSGP_ConnHdlr vc_conn;
1703 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001704 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 +02001705 vc_conn.done;
1706}
1707
Alexander Couzens5e307b42018-05-22 18:12:20 +02001708testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1709 /* MS <-> SGSN: GMM Attach
1710 * HLR -> SGSN: Cancel Location Request
1711 * HLR <- SGSN: Cancel Location Ack
1712 */
1713 var BSSGP_ConnHdlr vc_conn;
1714 f_init();
1715 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001716 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001717 vc_conn.done;
1718}
1719
1720
Alexander Couzensc87967a2018-05-22 16:09:54 +02001721private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1722 /* MS: perform regular attach */
1723 f_TC_attach(id);
1724
1725 /* HLR: cancel the location request */
1726 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1727 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1728 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1729
1730 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001731 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001732 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001733
1734 setverdict(pass);
1735}
1736
1737testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1738 /* MS <-> SGSN: GMM Attach
1739 * HLR -> SGSN: Cancel Location Request
1740 * HLR <- SGSN: Cancel Location Ack
1741 * MS <- SGSN: Detach Request
1742 * SGSN-> MS: Detach Complete
1743 */
1744 var BSSGP_ConnHdlr vc_conn;
1745 f_init();
1746 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001747 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001748 vc_conn.done;
1749}
1750
1751
Alexander Couzens6c47f292018-05-22 17:09:49 +02001752private function f_hlr_location_cancel_request_unknown_subscriber(
1753 charstring id,
1754 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1755
1756 /* HLR: cancel the location request */
1757 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1758
1759 /* cause 2 = IMSI_UNKNOWN */
1760 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1761
1762 setverdict(pass);
1763}
1764
1765private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001766 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001767}
1768
1769testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1770 /* HLR -> SGSN: Cancel Location Request
1771 * HLR <- SGSN: Cancel Location Error
1772 */
1773
1774 var BSSGP_ConnHdlr vc_conn;
1775 f_init();
1776 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001777 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 +02001778 vc_conn.done;
1779}
1780
1781private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001782 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001783}
1784
1785testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1786 /* HLR -> SGSN: Cancel Location Request
1787 * HLR <- SGSN: Cancel Location Error
1788 */
1789
1790 var BSSGP_ConnHdlr vc_conn;
1791 f_init();
1792 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001793 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 +02001794 vc_conn.done;
1795}
1796
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001797private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1798 f_TC_attach(id);
1799 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1800}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001801
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001802testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1803 /* MS <-> SGSN: Attach
1804 * MS -> SGSN: Detach Req (Power off)
1805 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1806 */
1807 var BSSGP_ConnHdlr vc_conn;
1808 var integer id := 33;
1809 var charstring imsi := hex2str(f_gen_imsi(id));
1810
1811 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001812 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001813 vc_conn.done;
1814
1815 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1816}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001817
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001818/* Attempt an attach, but loose the Identification Request (IMEI) */
1819private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1820 var integer count_req := 0;
1821 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1822
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001823 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001824
1825 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001826 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001827 /* break */
1828 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001829 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001830 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001831 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001832 repeat;
1833 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001834 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001835 /* ignore ID REQ IMEI */
1836 count_req := count_req + 1;
1837 repeat;
1838 }
1839 }
1840 if (count_req != 5) {
1841 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001842 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001843 }
1844 setverdict(pass);
1845}
1846
1847testcase TC_attach_no_imei_response() runs on test_CT {
1848 /* MS -> SGSN: Attach Request IMSI
1849 * MS <- SGSN: Identity Request IMSI (optional)
1850 * MS -> SGSN: Identity Response IMSI (optional)
1851 * MS <- SGSN: Identity Request IMEI
1852 * MS -x SGSN: no response
1853 * MS <- SGSN: re-send: Identity Request IMEI 4x
1854 * MS <- SGSN: Attach Reject
1855 */
1856 var BSSGP_ConnHdlr vc_conn;
1857 f_init();
1858 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001859 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 +02001860 vc_conn.done;
1861}
1862
Alexander Couzens53f20562018-06-12 16:24:12 +02001863/* Attempt an attach, but loose the Identification Request (IMSI) */
1864private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1865 var integer count_req := 0;
1866 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1867
1868 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1869 g_pars.p_tmsi := 'c0000035'O;
1870
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001871 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02001872
1873 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001874 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001875 /* break */
1876 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001877 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001878 /* ignore ID REQ IMSI */
1879 count_req := count_req + 1;
1880 repeat;
1881 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001882 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001883 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001884 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001885 repeat;
1886 }
1887 }
1888 if (count_req != 5) {
1889 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001890 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001891 }
1892 setverdict(pass);
1893}
1894
1895testcase TC_attach_no_imsi_response() runs on test_CT {
1896 /* MS -> SGSN: Attach Request TMSI (unknown)
1897 * MS <- SGSN: Identity Request IMEI (optional)
1898 * MS -> SGSN: Identity Response IMEI (optional)
1899 * MS <- SGSN: Identity Request IMSI
1900 * MS -x SGSN: no response
1901 * MS <- SGSN: re-send: Identity Request IMSI 4x
1902 * MS <- SGSN: Attach Reject
1903 */
1904 var BSSGP_ConnHdlr vc_conn;
1905 f_init();
1906 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001907 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 +02001908 vc_conn.done;
1909}
1910
Alexander Couzenscf818962018-06-05 18:00:00 +02001911private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1912 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1913}
1914
1915testcase TC_attach_check_subscriber_list() runs on test_CT {
1916 /* MS <-> SGSN: Attach
1917 * VTY -> SGSN: Check if MS is in subscriber cache
1918 */
1919 var BSSGP_ConnHdlr vc_conn;
1920 var integer id := 34;
1921 var charstring imsi := hex2str(f_gen_imsi(id));
1922
1923 f_init();
1924 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001925 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001926 vc_conn.done;
1927
1928 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1929 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1930}
1931
Alexander Couzensf9858652018-06-07 16:14:53 +02001932private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1933 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1934 var BssgpDecoded bd;
1935
1936 /* unregister the old IMSI */
1937 f_bssgp_client_unregister(g_pars.imsi);
1938 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001939 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001940 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001941
1942 /* there is no auth */
1943 g_pars.net.expect_auth := false;
1944
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001945 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02001946 f_gmm_auth();
1947 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001948 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001949 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001950 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001951 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001952 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001953 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001954 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001955 setverdict(pass);
1956 }
1957 }
1958}
Alexander Couzens03d12242018-08-07 16:13:52 +02001959
1960private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1961
1962 f_TC_attach_closed_foreign(id);
1963 f_TC_attach_closed_imsi_added(id);
1964
1965}
1966
1967
Alexander Couzensf9858652018-06-07 16:14:53 +02001968testcase TC_attach_closed_add_vty() runs on test_CT {
1969 /* VTY-> SGSN: policy close
1970 * MS -> SGSN: Attach Request
1971 * MS <- SGSN: Identity Request IMSI
1972 * MS -> SGSN: Identity Response IMSI
1973 * MS <- SGSN: Attach Reject
1974 * VTY-> SGSN: policy imsi-acl add IMSI
1975 * MS -> SGSN: Attach Request
1976 * MS <- SGSN: Identity Request IMSI
1977 * MS -> SGSN: Identity Response IMSI
1978 * MS <- SGSN: Identity Request IMEI
1979 * MS -> SGSN: Identity Response IMEI
1980 * MS <- SGSN: Attach Accept
1981 */
1982 var BSSGP_ConnHdlr vc_conn;
1983 f_init();
1984 f_sleep(1.0);
1985 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1986 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001987 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1988 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001989 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001990 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001991 vc_conn.done;
1992}
1993
Alexander Couzens0085bd72018-06-12 19:08:44 +02001994/* Attempt an attach, but never answer a Attach Complete */
1995private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1996 var integer count_req := 0;
1997
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001998 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02001999 f_gmm_auth();
2000
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002001 timer T := 10.0;
2002 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002003 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002004 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002005 /* break */
2006 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002007 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002008 /* ignore */
2009 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002010 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002011 repeat;
2012 }
2013 }
2014 if (count_req != 5) {
2015 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002016 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002017 }
2018 setverdict(pass);
2019}
2020
2021testcase TC_attach_check_complete_resend() runs on test_CT {
2022 /* MS -> SGSN: Attach Request IMSI
2023 * MS <- SGSN: Identity Request *
2024 * MS -> SGSN: Identity Response *
2025 * MS <- SGSN: Attach Complete 5x
2026 */
2027 var BSSGP_ConnHdlr vc_conn;
2028 f_init();
2029 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002030 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 +02002031 vc_conn.done;
2032}
2033
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002034private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
2035 var BssgpDecoded bd;
2036
2037 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002038 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit), bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002039 alt {
2040 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02002041 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002042 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002043 setverdict(pass);
2044 }
2045 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
2046 setverdict(fail, "Unexpected RAU Reject");
2047 mtc.stop;
2048 }
2049 [] BSSGP[bssgp].receive { repeat; }
2050 }
2051}
2052
Alexander Couzensbfda9212018-07-31 03:17:33 +02002053private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
2054 var BssgpDecoded bd;
2055
2056 /* first perform regular attach */
2057 f_TC_attach(id);
2058
2059 /* then send RAU */
2060 f_routing_area_update(g_pars.ra);
2061
2062 /* do another RAU */
2063 f_routing_area_update(g_pars.ra);
2064
2065 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2066}
2067
2068testcase TC_attach_rau_a_a() runs on test_CT {
2069 /* MS <-> SGSN: Successful Attach
2070 * MS -> SGSN: Routing Area Update Request
2071 * MS <- SGSN: Routing Area Update Accept
2072 * MS -> SGSN: Routing Area Update Request
2073 * MS <- SGSN: Routing Area Update Accept
2074 * MS -> SGSN: Detach (PowerOff)
2075 */
2076 var BSSGP_ConnHdlr vc_conn;
2077 f_init();
2078 f_sleep(1.0);
2079 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2080 vc_conn.done;
2081}
2082
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002083private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
2084 var BssgpDecoded bd;
2085
2086 f_TC_attach(id);
2087
2088 log("attach complete sending rau");
2089 f_routing_area_update(g_pars.ra, 0);
2090
2091 log("rau complete unregistering");
2092 f_bssgp_client_unregister(g_pars.imsi);
2093 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2094
2095 log("sending second RAU via different RA");
2096 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2097
2098 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2099}
2100
2101testcase TC_attach_rau_a_b() runs on test_CT {
2102 /* MS <-> SGSN: Successful Attach
2103 * MS -> SGSN: Routing Area _a_ Update Request
2104 * MS <- SGSN: Routing Area _a_ Update Accept
2105 * MS -> SGSN: Routing Area _b_ Update Request
2106 * MS <- SGSN: Routing Area _b_ Update Accept
2107 * MS -> SGSN: Detach (PowerOff)
2108 */
2109 var BSSGP_ConnHdlr vc_conn;
2110 f_init();
2111 f_sleep(1.0);
2112 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2113 vc_conn.done;
2114}
2115
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002116private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2117 var integer count_req := 0;
2118 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2119 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
2120 var BssgpDecoded bd;
2121
2122 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2123
2124 alt {
2125 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2126 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2127 mtc.stop;
2128 }
2129 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2130 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2131 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2132 repeat;
2133 }
2134 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2135 /* send out a second GMM_Attach Request.
2136 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2137 * of the same content */
2138 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2139 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
2140 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2141 }
2142 }
2143 f_sleep(1.0);
2144
2145 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2146 alt {
2147 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2148 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2149 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2150 repeat;
2151 }
2152 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2153 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2154 mtc.stop;
2155 }
2156 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2157 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2158 mtc.stop;
2159 }
2160 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2161 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2162 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2163 setverdict(pass);
2164 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2165 }
2166 }
2167}
2168
2169testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2170 /* Testing if the SGSN ignore Attach Request with the exact same content */
2171 /* MS -> SGSN: Attach Request IMSI
2172 * MS <- SGSN: Identity Request IMSI (optional)
2173 * MS -> SGSN: Identity Response IMSI (optional)
2174 * MS <- SGSN: Identity Request IMEI
2175 * MS -> SGSN: Attach Request (2nd)
2176 * MS <- SGSN: Identity Response IMEI
2177 * MS <- SGSN: Attach Accept
2178 * MS -> SGSN: Attach Complete
2179 */
2180 var BSSGP_ConnHdlr vc_conn;
2181 f_init();
2182 f_sleep(1.0);
2183 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2184 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2185 vc_conn.done;
2186}
2187
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002188private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
2189 var BssgpDecoded bd;
2190 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2191
2192 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2193
2194 /* send Attach Request */
2195 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2196 * 3G auth vectors */
2197 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2198 /* The thing is, if the solSACapability is 'omit', then the
2199 * revisionLevelIndicatior is at the wrong place! */
2200 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2201 f_send_l3_gmm_llc(attach_req);
2202
2203 /* do the auth */
2204 var PDU_L3_MS_SGSN l3_mo;
2205 var PDU_L3_SGSN_MS l3_mt;
2206 var default di := activate(as_mm_identity());
2207
2208 var GSUP_IE auth_tuple;
2209 var template AuthenticationParameterAUTNTLV autn;
2210
2211 g_pars.vec := f_gen_auth_vec_3g();
2212 autn := {
2213 elementIdentifier := '28'O,
2214 lengthIndicator := lengthof(g_pars.vec.autn),
2215 autnValue := g_pars.vec.autn
2216 };
2217 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2218 g_pars.vec.sres,
2219 g_pars.vec.kc,
2220 g_pars.vec.ik,
2221 g_pars.vec.ck,
2222 g_pars.vec.autn,
2223 g_pars.vec.res));
2224 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2225 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2226 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2227
2228 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2229 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2230 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2231
2232 /* send the gmm auth failure with resync IE */
2233 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2234
2235 /* wait for the GSUP resync request */
2236 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2237 g_pars.imsi,
2238 g_pars.vec.auts,
2239 g_pars.vec.rand));
2240
2241 /* generate new key material */
2242 g_pars.vec := f_gen_auth_vec_3g();
2243 autn := {
2244 elementIdentifier := '28'O,
2245 lengthIndicator := lengthof(g_pars.vec.autn),
2246 autnValue := g_pars.vec.autn
2247 };
2248
2249 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2250 g_pars.vec.sres,
2251 g_pars.vec.kc,
2252 g_pars.vec.ik,
2253 g_pars.vec.ck,
2254 g_pars.vec.autn,
2255 g_pars.vec.res));
2256 /* send new key material */
2257 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2258
2259 /* wait for the new Auth Request */
2260 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2261 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2262 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2263 l3_mt := bd.l3_mt;
2264 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2265 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2266 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2267 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2268 valueField := substr(g_pars.vec.res, 0, 4)
2269 };
2270 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2271 elementIdentifier := '21'O,
2272 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2273 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2274 };
2275 l3_mo := valueof(auth_ciph_resp);
2276 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2277 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2278 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2279 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2280 }
2281 f_send_l3_gmm_llc(l3_mo);
2282 deactivate(di);
2283
2284 /* Expect SGSN to perform LU with HLR */
2285 f_gmm_gsup_lu_isd();
2286
2287 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2288 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2289 }
2290 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2291 setverdict(pass);
2292}
2293
2294testcase TC_attach_usim_resync() runs on test_CT {
2295 /* MS -> SGSN: Attach Request
2296 * MS <- SGSN: Identity Request IMSI
2297 * MS -> SGSN: Identity Response IMSI
2298 * MS <- SGSN: Identity Request IMEI
2299 * MS -> SGSN: Identity Response IMEI
2300 * HLR<- SGSN: SAI Request
2301 * HLR-> SGSN: SAI Response
2302 * MS <- SGSN: Auth Request
2303 * MS -> SGSN: Auth Failure (with AUTS)
2304 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2305 * HLR-> SGSN: SAI Response (new key material)
2306 * MS <- SGSN: Auth Request (new key material)
2307 * MS -> SGSN: Auth Response
2308 * MS <- SGSN: Attach Accept
2309 * MS -> SGSN: Attach Complete
2310 */
2311 var BSSGP_ConnHdlr vc_conn;
2312 f_init();
2313 f_sleep(1.0);
2314 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2315 vc_conn.done;
2316}
2317
Harald Weltea05b8072019-04-23 22:35:05 +02002318
2319/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2320private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2321 f_gmm_attach(false, false);
2322 f_sleep(1.0);
2323 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2324 /* try to detach to check if SGSN is still alive */
2325 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2326}
2327testcase TC_llc_null() runs on test_CT {
2328 var BSSGP_ConnHdlr vc_conn;
2329 f_init();
2330 f_sleep(1.0);
2331 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2332 vc_conn.done;
2333}
2334
Harald Welte645a1512019-04-23 23:18:23 +02002335/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2336private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2337 f_gmm_attach(false, false);
2338 f_sleep(1.0);
2339 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2340 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP)));
2341 setverdict(pass);
2342}
2343testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2344 var BSSGP_ConnHdlr vc_conn;
2345 f_init();
2346 f_sleep(1.0);
2347 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2348 vc_conn.done;
2349}
2350
2351/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2352private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2353 f_gmm_attach(false, false);
2354 f_sleep(1.0);
2355 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
2356 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP)));
2357 setverdict(pass);
2358}
2359testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2360 var BSSGP_ConnHdlr vc_conn;
2361 f_init();
2362 f_sleep(1.0);
2363 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2364 vc_conn.done;
2365}
2366
Harald Welte2aaac1b2019-05-02 10:02:53 +02002367/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2368private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2369 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2370 var template (value) XID_Information xid;
2371 var template XID_Information xid_rx;
2372
2373 /* first perform regular attach */
2374 f_TC_attach(id);
2375 /* then activate PDP context */
2376 f_pdp_ctx_act(apars);
2377
2378 /* start MO XID */
2379 xid := { ts_XID_L3(''O) };
2380 xid_rx := { tr_XID_L3(''O) };
2381 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2382 alt {
2383 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(xid_rx, apars.sapi)));
2384 [] as_xid(apars);
2385 }
2386 setverdict(pass);
2387}
2388testcase TC_xid_empty_l3() runs on test_CT {
2389 var BSSGP_ConnHdlr vc_conn;
2390 f_init();
2391 f_sleep(1.0);
2392 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2393 vc_conn.done;
2394}
2395
2396private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2397 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2398 var template (value) XID_Information xid;
2399 var template XID_Information xid_rx;
2400
2401 /* first perform regular attach */
2402 f_TC_attach(id);
2403 /* then activate PDP context */
2404 f_pdp_ctx_act(apars);
2405
2406 /* start MO XID */
2407 xid := { ts_XID_N201U(1234) };
2408 xid_rx := { tr_XID_N201U(1234) };
2409 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2410 alt {
2411 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi)));
2412 [] as_xid(apars);
2413 }
2414 setverdict(pass);
2415}
2416testcase TC_xid_n201u() runs on test_CT {
2417 var BSSGP_ConnHdlr vc_conn;
2418 f_init();
2419 f_sleep(1.0);
2420 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2421 vc_conn.done;
2422}
2423
Alexander Couzens6bee0872019-05-11 01:48:50 +02002424private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2425 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2426
2427 /* first perform regular attach */
2428 f_TC_attach(id);
2429 /* then activate PDP context */
2430 f_pdp_ctx_act(apars);
2431 /* do a normal detach */
2432 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2433}
2434
2435testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2436 /* MS -> SGSN: Attach Request
2437 * MS <-> SGSN: [..]
2438 * MS -> SGSN: Attach Complete
2439 * MS -> SGSN: PDP Activate Request
2440 * MS <- SGSN: PDP Activate Accept
2441 * MS -> SGSN: GMM Detach Request
2442 * MS <- SGSN: GMM Detach Accept
2443 */
2444 var BSSGP_ConnHdlr vc_conn;
2445 f_init();
2446 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2447 vc_conn.done;
2448}
Harald Welte645a1512019-04-23 23:18:23 +02002449
2450
Harald Welte5ac31492018-02-15 20:39:13 +01002451control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002452 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002453 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002454 execute( TC_attach_umts_aka_umts_res() );
2455 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002456 execute( TC_attach_auth_id_timeout() );
2457 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002458 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002459 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002460 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002461 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002462 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002463 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002464 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002465 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002466 execute( TC_attach_closed_add_vty(), 20.0 );
2467 execute( TC_attach_check_subscriber_list(), 20.0 );
2468 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002469 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002470 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2471 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2472 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2473 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002474 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002475 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002476 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002477 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002478 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002479 execute( TC_detach_unknown_nopoweroff() );
2480 execute( TC_detach_unknown_poweroff() );
2481 execute( TC_detach_nopoweroff() );
2482 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002483 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002484 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002485 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002486 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002487 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002488 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002489 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002490 execute( TC_attach_restart_ctr_echo() );
2491 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002492 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002493 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2494 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002495 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002496 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002497 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002498
Harald Welte2aaac1b2019-05-02 10:02:53 +02002499 execute( TC_xid_empty_l3() );
2500 execute( TC_xid_n201u() );
2501
Harald Weltea05b8072019-04-23 22:35:05 +02002502 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002503 execute( TC_llc_sabm_dm_llgmm() );
2504 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002505}
Harald Welte96a33b02018-02-04 10:36:22 +01002506
2507
2508
2509}