blob: 1f63dfaeb9f277fc76f8bc87e6feeed4766fe7d4 [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 }
Alexander Couzens44aa0772019-05-11 01:21:03 +0200927 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(?)) -> value bd {
928 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
929 mtc.stop;
930 }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100931 [power_off] T.timeout {
932 setverdict(pass);
933 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200934 [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 +0100935 g_pars.ra := omit;
936 setverdict(pass);
937 /* TODO: check if any PDP contexts are deactivated on network side? */
938 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200939 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100940 }
941}
942
943/* IMSI DETACH (non-power-off) for unknown TLLI */
944private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
945 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
946}
947testcase TC_detach_unknown_nopoweroff() runs on test_CT {
948 var BSSGP_ConnHdlr vc_conn;
949 f_init();
950 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200951 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100952 vc_conn.done;
953}
954
955/* IMSI DETACH (power-off) for unknown TLLI */
956private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
957 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
958}
959testcase TC_detach_unknown_poweroff() runs on test_CT {
960 var BSSGP_ConnHdlr vc_conn;
961 f_init();
962 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200963 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100964 vc_conn.done;
965}
966
967/* IMSI DETACH (non-power-off) for known TLLI */
968private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
969 /* first perform regular attach */
970 f_TC_attach(id);
971
972 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
973}
974testcase TC_detach_nopoweroff() runs on test_CT {
975 var BSSGP_ConnHdlr vc_conn;
976 f_init();
977 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200978 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100979 vc_conn.done;
980}
981
982/* IMSI DETACH (power-off) for known TLLI */
983private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
984 /* first perform regular attach */
985 f_TC_attach(id);
986
987 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
988}
989testcase TC_detach_poweroff() runs on test_CT {
990 var BSSGP_ConnHdlr vc_conn;
991 f_init();
992 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200993 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100994 vc_conn.done;
995}
996
Harald Welteeded9ad2018-02-17 20:57:34 +0100997type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100998 BIT3 tid, /* L3 Transaction ID */
999 BIT4 nsapi, /* SNDCP NSAPI */
1000 BIT4 sapi, /* LLC SAPI */
1001 QoSV qos, /* QoS parameters */
1002 PDPAddressV addr, /* IP address */
1003 octetstring apn optional, /* APN name */
1004 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1005 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001006 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001007 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001008
Harald Welte822f9102018-02-18 20:39:06 +01001009 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1010 OCT4 ggsn_tei_u, /* GGSN TEI User */
1011 octetstring ggsn_ip_c, /* GGSN IP Control */
1012 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001013 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001014
Harald Welte822f9102018-02-18 20:39:06 +01001015 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1016 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1017 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1018 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001019};
1020
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001021
1022private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1023 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1024 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1025 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1026 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1027 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1028 f_gtp_register_teid(apars.ggsn_tei_c);
1029 f_gtp_register_teid(apars.ggsn_tei_u);
1030}
1031
Harald Weltef7191672019-05-02 20:37:23 +02001032function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1033runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001034 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1035 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001036 var template Recovery_gtpc recovery := omit;
1037
1038 if (send_recovery) {
1039 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1040 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001041
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001042 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 +02001043 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001044 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1045 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1046 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1047 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1048 apars.sgsn_tei_c, apars.gtp_resp_cause,
1049 apars.ggsn_tei_c, apars.ggsn_tei_u,
1050 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001051 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1052 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001053 }
1054 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001055 [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 +01001056 setverdict(pass);
1057 }
Harald Weltef7191672019-05-02 20:37:23 +02001058 [exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001059 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001060 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001061 }
Harald Weltef7191672019-05-02 20:37:23 +02001062 [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 +01001063 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
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, ?))) {
1067 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1068 mtc.stop;
1069 }
1070 [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 +01001071 setverdict(pass);
1072 }
Harald Weltef7191672019-05-02 20:37:23 +02001073 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001074 }
1075}
1076
Harald Weltef7191672019-05-02 20:37:23 +02001077function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1078runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001079 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1080 var Gtp1cUnitdata g_ud;
1081
Harald Weltef7191672019-05-02 20:37:23 +02001082 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 +01001083 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1084 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001085 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001086 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1087 }
1088 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001089 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001090 setverdict(pass);
1091 }
Harald Weltef7191672019-05-02 20:37:23 +02001092 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001093 }
1094}
1095
Harald Weltef7191672019-05-02 20:37:23 +02001096function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1097runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001098 var Gtp1cUnitdata g_ud;
1099 var integer seq_nr := 23;
1100 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1101
Harald Weltef7191672019-05-02 20:37:23 +02001102 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001103 if (error_ind) {
1104 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1105 } else {
1106 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1107 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001108
1109 timer T := 5.0;
1110 T.start;
1111
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001112 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001113 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
1114 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001115 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001116 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1117 repeat;
1118 }
1119 [] T.timeout {
1120 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1121 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001122 }
1123}
1124
Harald Welte6f203162018-02-18 22:04:55 +01001125
Harald Welteeded9ad2018-02-17 20:57:34 +01001126/* Table 10.5.156/3GPP TS 24.008 */
1127template (value) QoSV t_QosDefault := {
1128 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1129 delayClass := '100'B, /* best effort */
1130 spare1 := '00'B,
1131 precedenceClass := '010'B, /* normal */
1132 spare2 := '0'B,
1133 peakThroughput := '0000'B, /* subscribed */
1134 meanThroughput := '00000'B, /* subscribed */
1135 spare3 := '000'B,
1136 deliverErroneusSDU := omit,
1137 deliveryOrder := omit,
1138 trafficClass := omit,
1139 maxSDUSize := omit,
1140 maxBitrateUplink := omit,
1141 maxBitrateDownlink := omit,
1142 sduErrorRatio := omit,
1143 residualBER := omit,
1144 trafficHandlingPriority := omit,
1145 transferDelay := omit,
1146 guaranteedBitRateUplink := omit,
1147 guaranteedBitRateDownlink := omit,
1148 sourceStatisticsDescriptor := omit,
1149 signallingIndication := omit,
1150 spare4 := omit,
1151 maxBitrateDownlinkExt := omit,
1152 guaranteedBitRateDownlinkExt := omit,
1153 maxBitrateUplinkExt := omit,
1154 guaranteedBitRateUplinkExt := omit,
1155 maxBitrateDownlinkExt2 := omit,
1156 guaranteedBitRateDownlinkExt2 := omit,
1157 maxBitrateUplinkExt2 := omit,
1158 guaranteedBitRateUplinkExt2 := omit
1159}
1160
1161/* 10.5.6.4 / 3GPP TS 24.008 */
1162template (value) PDPAddressV t_AddrIPv4dyn := {
1163 pdpTypeOrg := '0001'B, /* IETF */
1164 spare := '0000'B,
1165 pdpTypeNum := '21'O, /* IPv4 */
1166 addressInfo := omit
1167}
1168template (value) PDPAddressV t_AddrIPv6dyn := {
1169 pdpTypeOrg := '0001'B, /* IETF */
1170 spare := '0000'B,
1171 pdpTypeNum := '53'O, /* IPv6 */
1172 addressInfo := omit
1173}
1174
Harald Welte37692d82018-02-18 15:21:34 +01001175template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001176 tid := '000'B,
1177 nsapi := '0101'B, /* < 5 are reserved */
1178 sapi := '0011'B, /* 3/5/9/11 */
1179 qos := t_QosDefault,
1180 addr := t_AddrIPv4dyn,
1181 apn := omit,
1182 pco := omit,
1183 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001184 gtp_resp_cause := int2oct(128, 1),
1185 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001186
1187 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001188 ggsn_tei_c := f_rnd_octstring(4),
1189 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001190 ggsn_ip_c := f_inet_addr(ggsn_ip),
1191 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001192 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001193
Harald Welteeded9ad2018-02-17 20:57:34 +01001194 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001195 sgsn_tei_u := omit,
1196 sgsn_ip_c := omit,
1197 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001198}
1199
Harald Welte37692d82018-02-18 15:21:34 +01001200template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1201 connId := 1,
1202 remName := f_inet_ntoa(ip),
1203 remPort := GTP1U_PORT
1204}
1205
1206template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1207 connId := 1,
1208 remName := f_inet_ntoa(ip),
1209 remPort := GTP1C_PORT
1210}
1211
1212private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1213 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1214 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1215}
1216
Harald Weltef7191672019-05-02 20:37:23 +02001217private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
1218 [] BSSGP[gb_idx].receive(tr_BD_LLC(tr_LLC_XID_MT_CMD(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001219 repeat;
1220 }
1221}
1222
1223template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1224 pDU_SN_UNITDATA := {
1225 nsapi := nsapi,
1226 moreBit := ?,
1227 snPduType := '1'B,
1228 firstSegmentIndicator := ?,
1229 spareBit := ?,
1230 pcomp := ?,
1231 dcomp := ?,
1232 npduNumber := ?,
1233 segmentNumber := ?,
1234 npduNumberContinued := ?,
1235 dataSegmentSnUnitdataPdu := payload
1236 }
1237}
1238
1239/* simple case: single segment, no compression */
1240template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1241 pDU_SN_UNITDATA := {
1242 nsapi := nsapi,
1243 moreBit := '0'B,
1244 snPduType := '1'B,
1245 firstSegmentIndicator := '1'B,
1246 spareBit := '0'B,
1247 pcomp := '0000'B,
1248 dcomp := '0000'B,
1249 npduNumber := '0000'B,
1250 segmentNumber := '0000'B,
1251 npduNumberContinued := '00'O,
1252 dataSegmentSnUnitdataPdu := payload
1253 }
1254}
1255
1256/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001257private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1258runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001259 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1260 f_gtpu_send(apars, payload);
1261 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1262 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001263 [] as_xid(apars, gb_idx);
1264 [] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001265 }
1266}
1267
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001268/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001269private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1270runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001271 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1272 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1273 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001274 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001275 /* Expect PDU via GTP from SGSN on simulated GGSN */
1276 alt {
1277 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1278 }
1279}
1280
Harald Welteeded9ad2018-02-17 20:57:34 +01001281private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001282 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001283
1284 /* first perform regular attach */
1285 f_TC_attach(id);
1286
1287 f_pdp_ctx_act(apars);
1288}
1289testcase TC_attach_pdp_act() runs on test_CT {
1290 var BSSGP_ConnHdlr vc_conn;
1291 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001292 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001293 vc_conn.done;
1294}
Harald Welteb2124b22018-02-16 22:26:56 +01001295
Harald Welte835b15f2018-02-18 14:39:11 +01001296/* PDP Context activation for not-attached subscriber; expect fail */
1297private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001298 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001299 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 +01001300 apars.apn, apars.pco));
1301 alt {
1302 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001303 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001304 setverdict(pass);
1305 }
1306 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1307 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001308 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001309 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001310 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001311 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
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 { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001315 }
1316}
1317testcase TC_pdp_act_unattached() runs on test_CT {
1318 var BSSGP_ConnHdlr vc_conn;
1319 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001320 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001321 vc_conn.done;
1322}
1323
Harald Welte37692d82018-02-18 15:21:34 +01001324/* ATTACH + PDP CTX ACT + user plane traffic */
1325private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1326 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1327
1328 /* first perform regular attach */
1329 f_TC_attach(id);
1330 /* then activate PDP context */
1331 f_pdp_ctx_act(apars);
1332 /* then transceive a downlink PDU */
1333 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1334 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1335}
1336testcase TC_attach_pdp_act_user() runs on test_CT {
1337 var BSSGP_ConnHdlr vc_conn;
1338 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001339 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001340 vc_conn.done;
1341}
1342
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001343/* ATTACH + PDP CTX ACT; reject from GGSN */
1344private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1345 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1346
1347 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1348 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1349
1350 /* first perform regular attach */
1351 f_TC_attach(id);
1352 /* then activate PDP context */
1353 f_pdp_ctx_act(apars);
1354}
1355testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1356 var BSSGP_ConnHdlr vc_conn;
1357 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001358 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001359 vc_conn.done;
1360}
Harald Welte835b15f2018-02-18 14:39:11 +01001361
Harald Welte6f203162018-02-18 22:04:55 +01001362/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1363private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1364 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1365
1366 /* first perform regular attach */
1367 f_TC_attach(id);
1368 /* then activate PDP context */
1369 f_pdp_ctx_act(apars);
1370 /* then transceive a downlink PDU */
1371 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1372 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1373
1374 f_pdp_ctx_deact_mo(apars, '00'O);
1375}
1376testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1377 var BSSGP_ConnHdlr vc_conn;
1378 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001379 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 +01001380 vc_conn.done;
1381}
1382
Harald Welte57b9b7f2018-02-18 22:28:13 +01001383/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1384private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1385 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1386
1387 /* first perform regular attach */
1388 f_TC_attach(id);
1389 /* then activate PDP context */
1390 f_pdp_ctx_act(apars);
1391 /* then transceive a downlink PDU */
1392 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1393 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1394
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001395 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001396}
1397testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1398 var BSSGP_ConnHdlr vc_conn;
1399 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001400 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 +01001401 vc_conn.done;
1402}
1403
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001404/* ATTACH + ATTACH (2nd) */
1405private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1406 g_pars.t_guard := 5.0;
1407
1408 /* first perform regular attach */
1409 f_TC_attach(id);
1410
1411 /* second to perform regular attach */
1412 f_TC_attach(id);
1413}
1414
1415
1416testcase TC_attach_second_attempt() runs on test_CT {
1417 var BSSGP_ConnHdlr vc_conn;
1418 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001419 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001420 vc_conn.done;
1421}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001422
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001423private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001424 var Gtp1cUnitdata g_ud;
1425 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1426
1427 /* first perform regular attach */
1428 f_TC_attach(id);
1429 /* Activate a pdp context against the GGSN */
1430 f_pdp_ctx_act(apars);
1431 /* Wait to receive first echo request and send initial Restart counter */
1432 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1433 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1434 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1435 }
1436 /* Wait to receive second echo request and send incremented Restart
1437 counter. This will fake a restarted GGSN, and pdp ctx allocated
1438 should be released by SGSN */
1439 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1440 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1441 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1442 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1443 }
1444 var OCT1 cause_network_failure := int2oct(38, 1)
1445 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001446 [] 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 +02001447 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001448 setverdict(pass);
1449 }
1450 [] as_xid(apars);
1451 }
1452 setverdict(pass);
1453}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001454/* ATTACH + trigger Recovery procedure through EchoResp */
1455testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001456 var BSSGP_ConnHdlr vc_conn;
1457 g_use_echo := true
1458 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001459 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 +02001460 vc_conn.done;
1461 g_use_echo := false
1462}
1463
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001464private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1465 var Gtp1cUnitdata g_ud;
1466 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1467 var integer seq_nr := 23;
1468 var GtpPeer peer;
1469 /* first perform regular attach */
1470 f_TC_attach(id);
1471
1472 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1473 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1474 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1475 f_pdp_ctx_act(apars, true);
1476
1477 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1478/* received. */
1479 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1480
1481 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1482 would be great to have an active pdp context here before triggering
1483 Recovery, and making sure the the DEACT request is sent by the SGSN.
1484 */
1485
1486 /* Activate a pdp context against the GGSN, send incremented Recovery
1487 IE. This should trigger the recovery path, but still this specific
1488 CTX activation should work. */
1489 apars.exp_rej_cause := omit; /* default value for tests */
1490 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1491 f_pdp_ctx_act(apars, true);
1492
1493 setverdict(pass);
1494}
1495/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1496testcase TC_attach_restart_ctr_create() runs on test_CT {
1497 var BSSGP_ConnHdlr vc_conn;
1498 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001499 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 +02001500 vc_conn.done;
1501}
1502
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001503/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1504private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1505 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1506 var integer seq_nr := 23;
1507 var GtpPeer peer;
1508 var integer i;
1509
1510 /* first perform regular attach */
1511 f_TC_attach(id);
1512 /* then activate PDP context */
1513 f_pdp_ctx_act(apars);
1514
Alexander Couzens0e510e62018-07-28 23:06:00 +02001515 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001516 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1517 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1518
1519 for (i := 0; i < 5; i := i+1) {
1520 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001521 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001522 [] as_xid(apars);
1523 }
1524 }
1525
1526 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1527
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001528 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001529 setverdict(pass);
1530}
1531testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1532 var BSSGP_ConnHdlr vc_conn;
1533 f_init();
1534 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001535 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 +02001536 vc_conn.done;
1537}
1538
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001539/* ATTACH + PDP CTX ACT dropped + retrans */
1540private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1541 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1542 var Gtp1cUnitdata g_ud_first, g_ud_second;
1543 /* first perform regular attach */
1544 f_TC_attach(id);
1545
1546 /* then activate PDP context on the Gb side */
1547 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1548 apars.apn, apars.pco), 0);
1549
1550 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1551 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1552 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1553 if (g_ud_first != g_ud_second) {
1554 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1555 mtc.stop;
1556 }
1557 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1558 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1559 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1560 apars.sgsn_tei_c, apars.gtp_resp_cause,
1561 apars.ggsn_tei_c, apars.ggsn_tei_u,
1562 apars.nsapi,
1563 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1564 omit, omit));
1565 }
1566 BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {}
1567
1568 /* Now the same with Deact */
1569 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1570 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1571 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1572 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1573 if (g_ud_first != g_ud_second) {
1574 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1575 mtc.stop;
1576 }
1577 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1578 BSSGP[0].clear;
1579 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1580 }
1581 alt {
1582 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
1583 setverdict(pass);
1584 }
1585 [] as_xid(apars, 0);
1586 }
1587
1588 setverdict(pass);
1589}
1590testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1591 var BSSGP_ConnHdlr vc_conn;
1592 f_init();
1593 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1594 vc_conn.done;
1595}
1596
1597/* Test that SGSN GTP response retransmit queue works fine */
1598private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1599 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1600 var integer seq_nr := 23;
1601 var Gtp1cUnitdata g_ud_first, g_ud_second;
1602 var template Gtp1cUnitdata g_delete_req;
1603 /* first perform regular attach + PDP context act */
1604 f_TC_attach(id);
1605 f_pdp_ctx_act(apars);
1606
1607 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1608 BSSGP[0].clear;
1609 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1610 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1611 GTP.send(g_delete_req);
1612 alt {
1613 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
1614 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1615 }
1616 [] as_xid(apars, 0);
1617 }
1618 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1619 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1620 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1621 mtc.stop;
1622 }
1623 };
1624
1625 /* Send duplicate DeleteCtxReq */
1626 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1627 GTP.send(g_delete_req);
1628 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1629 if (g_ud_first != g_ud_second) {
1630 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1631 mtc.stop;
1632 }
1633 }
1634
1635 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1636 * is handled differently by SGSN (expect "non-existent" cause) */
1637 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1638 GTP.send(g_delete_req);
1639 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1640 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1641 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1642 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1643 mtc.stop;
1644 }
1645 }
1646
1647 setverdict(pass);
1648}
1649testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1650 var BSSGP_ConnHdlr vc_conn;
1651 f_init();
1652 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1653 vc_conn.done;
1654}
1655
Alexander Couzens5e307b42018-05-22 18:12:20 +02001656private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1657 /* MS: perform regular attach */
1658 f_TC_attach(id);
1659
1660 /* HLR: cancel the location request */
1661 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1662 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001663
1664 /* ensure no Detach Request got received */
1665 timer T := 5.0;
1666 T.start;
1667 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001668 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001669 T.stop;
1670 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001671 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001672 }
1673 [] T.timeout {
1674 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001675 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001676 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001677 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001678 repeat;
1679 }
1680 }
1681}
1682
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001683/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1684private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1685 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1686
1687 /* first perform regular attach */
1688 f_TC_attach(id);
1689 /* then activate PDP context */
1690 f_pdp_ctx_act(apars);
1691 /* then transceive a downlink PDU */
1692 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1693
1694 /* Send Error indication as response from upload PDU and expect deact towards MS */
1695 f_pdp_ctx_deact_mt(apars, true);
1696}
1697testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1698 var BSSGP_ConnHdlr vc_conn;
1699 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001700 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 +02001701 vc_conn.done;
1702}
1703
Alexander Couzens5e307b42018-05-22 18:12:20 +02001704testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1705 /* MS <-> SGSN: GMM Attach
1706 * HLR -> SGSN: Cancel Location Request
1707 * HLR <- SGSN: Cancel Location Ack
1708 */
1709 var BSSGP_ConnHdlr vc_conn;
1710 f_init();
1711 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001712 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001713 vc_conn.done;
1714}
1715
1716
Alexander Couzensc87967a2018-05-22 16:09:54 +02001717private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1718 /* MS: perform regular attach */
1719 f_TC_attach(id);
1720
1721 /* HLR: cancel the location request */
1722 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1723 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1724 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1725
1726 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001727 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 +02001728 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001729
1730 setverdict(pass);
1731}
1732
1733testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1734 /* MS <-> SGSN: GMM Attach
1735 * HLR -> SGSN: Cancel Location Request
1736 * HLR <- SGSN: Cancel Location Ack
1737 * MS <- SGSN: Detach Request
1738 * SGSN-> MS: Detach Complete
1739 */
1740 var BSSGP_ConnHdlr vc_conn;
1741 f_init();
1742 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001743 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001744 vc_conn.done;
1745}
1746
1747
Alexander Couzens6c47f292018-05-22 17:09:49 +02001748private function f_hlr_location_cancel_request_unknown_subscriber(
1749 charstring id,
1750 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1751
1752 /* HLR: cancel the location request */
1753 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1754
1755 /* cause 2 = IMSI_UNKNOWN */
1756 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1757
1758 setverdict(pass);
1759}
1760
1761private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001762 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001763}
1764
1765testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1766 /* HLR -> SGSN: Cancel Location Request
1767 * HLR <- SGSN: Cancel Location Error
1768 */
1769
1770 var BSSGP_ConnHdlr vc_conn;
1771 f_init();
1772 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001773 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 +02001774 vc_conn.done;
1775}
1776
1777private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001778 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001779}
1780
1781testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1782 /* HLR -> SGSN: Cancel Location Request
1783 * HLR <- SGSN: Cancel Location Error
1784 */
1785
1786 var BSSGP_ConnHdlr vc_conn;
1787 f_init();
1788 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001789 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 +02001790 vc_conn.done;
1791}
1792
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001793private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1794 f_TC_attach(id);
1795 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1796}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001797
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001798testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1799 /* MS <-> SGSN: Attach
1800 * MS -> SGSN: Detach Req (Power off)
1801 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1802 */
1803 var BSSGP_ConnHdlr vc_conn;
1804 var integer id := 33;
1805 var charstring imsi := hex2str(f_gen_imsi(id));
1806
1807 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001808 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001809 vc_conn.done;
1810
1811 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1812}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001813
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001814/* Attempt an attach, but loose the Identification Request (IMEI) */
1815private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1816 var integer count_req := 0;
1817 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1818
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001819 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 +02001820
1821 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001822 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001823 /* break */
1824 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001825 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001826 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001827 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001828 repeat;
1829 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001830 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001831 /* ignore ID REQ IMEI */
1832 count_req := count_req + 1;
1833 repeat;
1834 }
1835 }
1836 if (count_req != 5) {
1837 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001838 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001839 }
1840 setverdict(pass);
1841}
1842
1843testcase TC_attach_no_imei_response() runs on test_CT {
1844 /* MS -> SGSN: Attach Request IMSI
1845 * MS <- SGSN: Identity Request IMSI (optional)
1846 * MS -> SGSN: Identity Response IMSI (optional)
1847 * MS <- SGSN: Identity Request IMEI
1848 * MS -x SGSN: no response
1849 * MS <- SGSN: re-send: Identity Request IMEI 4x
1850 * MS <- SGSN: Attach Reject
1851 */
1852 var BSSGP_ConnHdlr vc_conn;
1853 f_init();
1854 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001855 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 +02001856 vc_conn.done;
1857}
1858
Alexander Couzens53f20562018-06-12 16:24:12 +02001859/* Attempt an attach, but loose the Identification Request (IMSI) */
1860private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1861 var integer count_req := 0;
1862 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1863
1864 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1865 g_pars.p_tmsi := 'c0000035'O;
1866
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001867 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 +02001868
1869 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001870 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001871 /* break */
1872 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001873 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001874 /* ignore ID REQ IMSI */
1875 count_req := count_req + 1;
1876 repeat;
1877 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001878 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001879 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001880 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001881 repeat;
1882 }
1883 }
1884 if (count_req != 5) {
1885 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001886 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001887 }
1888 setverdict(pass);
1889}
1890
1891testcase TC_attach_no_imsi_response() runs on test_CT {
1892 /* MS -> SGSN: Attach Request TMSI (unknown)
1893 * MS <- SGSN: Identity Request IMEI (optional)
1894 * MS -> SGSN: Identity Response IMEI (optional)
1895 * MS <- SGSN: Identity Request IMSI
1896 * MS -x SGSN: no response
1897 * MS <- SGSN: re-send: Identity Request IMSI 4x
1898 * MS <- SGSN: Attach Reject
1899 */
1900 var BSSGP_ConnHdlr vc_conn;
1901 f_init();
1902 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001903 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 +02001904 vc_conn.done;
1905}
1906
Alexander Couzenscf818962018-06-05 18:00:00 +02001907private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1908 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1909}
1910
1911testcase TC_attach_check_subscriber_list() runs on test_CT {
1912 /* MS <-> SGSN: Attach
1913 * VTY -> SGSN: Check if MS is in subscriber cache
1914 */
1915 var BSSGP_ConnHdlr vc_conn;
1916 var integer id := 34;
1917 var charstring imsi := hex2str(f_gen_imsi(id));
1918
1919 f_init();
1920 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001921 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001922 vc_conn.done;
1923
1924 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1925 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1926}
1927
Alexander Couzensf9858652018-06-07 16:14:53 +02001928private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1929 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1930 var BssgpDecoded bd;
1931
1932 /* unregister the old IMSI */
1933 f_bssgp_client_unregister(g_pars.imsi);
1934 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001935 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001936 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001937
1938 /* there is no auth */
1939 g_pars.net.expect_auth := false;
1940
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001941 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 +02001942 f_gmm_auth();
1943 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001944 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001945 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001946 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001947 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001948 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001949 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001950 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001951 setverdict(pass);
1952 }
1953 }
1954}
Alexander Couzens03d12242018-08-07 16:13:52 +02001955
1956private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1957
1958 f_TC_attach_closed_foreign(id);
1959 f_TC_attach_closed_imsi_added(id);
1960
1961}
1962
1963
Alexander Couzensf9858652018-06-07 16:14:53 +02001964testcase TC_attach_closed_add_vty() runs on test_CT {
1965 /* VTY-> SGSN: policy close
1966 * MS -> SGSN: Attach Request
1967 * MS <- SGSN: Identity Request IMSI
1968 * MS -> SGSN: Identity Response IMSI
1969 * MS <- SGSN: Attach Reject
1970 * VTY-> SGSN: policy imsi-acl add IMSI
1971 * MS -> SGSN: Attach Request
1972 * MS <- SGSN: Identity Request IMSI
1973 * MS -> SGSN: Identity Response IMSI
1974 * MS <- SGSN: Identity Request IMEI
1975 * MS -> SGSN: Identity Response IMEI
1976 * MS <- SGSN: Attach Accept
1977 */
1978 var BSSGP_ConnHdlr vc_conn;
1979 f_init();
1980 f_sleep(1.0);
1981 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1982 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001983 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1984 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001985 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001986 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001987 vc_conn.done;
1988}
1989
Alexander Couzens0085bd72018-06-12 19:08:44 +02001990/* Attempt an attach, but never answer a Attach Complete */
1991private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1992 var integer count_req := 0;
1993
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001994 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 +02001995 f_gmm_auth();
1996
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001997 timer T := 10.0;
1998 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001999 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002000 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002001 /* break */
2002 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002003 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002004 /* ignore */
2005 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002006 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002007 repeat;
2008 }
2009 }
2010 if (count_req != 5) {
2011 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002012 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002013 }
2014 setverdict(pass);
2015}
2016
2017testcase TC_attach_check_complete_resend() runs on test_CT {
2018 /* MS -> SGSN: Attach Request IMSI
2019 * MS <- SGSN: Identity Request *
2020 * MS -> SGSN: Identity Response *
2021 * MS <- SGSN: Attach Complete 5x
2022 */
2023 var BSSGP_ConnHdlr vc_conn;
2024 f_init();
2025 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002026 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 +02002027 vc_conn.done;
2028}
2029
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002030private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
2031 var BssgpDecoded bd;
2032
2033 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002034 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 +02002035 alt {
2036 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02002037 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002038 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002039 setverdict(pass);
2040 }
2041 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
2042 setverdict(fail, "Unexpected RAU Reject");
2043 mtc.stop;
2044 }
2045 [] BSSGP[bssgp].receive { repeat; }
2046 }
2047}
2048
Alexander Couzensbfda9212018-07-31 03:17:33 +02002049private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
2050 var BssgpDecoded bd;
2051
2052 /* first perform regular attach */
2053 f_TC_attach(id);
2054
2055 /* then send RAU */
2056 f_routing_area_update(g_pars.ra);
2057
2058 /* do another RAU */
2059 f_routing_area_update(g_pars.ra);
2060
2061 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2062}
2063
2064testcase TC_attach_rau_a_a() runs on test_CT {
2065 /* MS <-> SGSN: Successful Attach
2066 * MS -> SGSN: Routing Area Update Request
2067 * MS <- SGSN: Routing Area Update Accept
2068 * MS -> SGSN: Routing Area Update Request
2069 * MS <- SGSN: Routing Area Update Accept
2070 * MS -> SGSN: Detach (PowerOff)
2071 */
2072 var BSSGP_ConnHdlr vc_conn;
2073 f_init();
2074 f_sleep(1.0);
2075 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2076 vc_conn.done;
2077}
2078
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002079private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
2080 var BssgpDecoded bd;
2081
2082 f_TC_attach(id);
2083
2084 log("attach complete sending rau");
2085 f_routing_area_update(g_pars.ra, 0);
2086
2087 log("rau complete unregistering");
2088 f_bssgp_client_unregister(g_pars.imsi);
2089 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2090
2091 log("sending second RAU via different RA");
2092 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2093
2094 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2095}
2096
2097testcase TC_attach_rau_a_b() runs on test_CT {
2098 /* MS <-> SGSN: Successful Attach
2099 * MS -> SGSN: Routing Area _a_ Update Request
2100 * MS <- SGSN: Routing Area _a_ Update Accept
2101 * MS -> SGSN: Routing Area _b_ Update Request
2102 * MS <- SGSN: Routing Area _b_ Update Accept
2103 * MS -> SGSN: Detach (PowerOff)
2104 */
2105 var BSSGP_ConnHdlr vc_conn;
2106 f_init();
2107 f_sleep(1.0);
2108 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2109 vc_conn.done;
2110}
2111
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002112private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2113 var integer count_req := 0;
2114 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2115 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
2116 var BssgpDecoded bd;
2117
2118 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2119
2120 alt {
2121 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2122 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2123 mtc.stop;
2124 }
2125 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2126 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2127 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2128 repeat;
2129 }
2130 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2131 /* send out a second GMM_Attach Request.
2132 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2133 * of the same content */
2134 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2135 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
2136 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2137 }
2138 }
2139 f_sleep(1.0);
2140
2141 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2142 alt {
2143 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2144 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2145 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2146 repeat;
2147 }
2148 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2149 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2150 mtc.stop;
2151 }
2152 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2153 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2154 mtc.stop;
2155 }
2156 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2157 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2158 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2159 setverdict(pass);
2160 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2161 }
2162 }
2163}
2164
2165testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2166 /* Testing if the SGSN ignore Attach Request with the exact same content */
2167 /* MS -> SGSN: Attach Request IMSI
2168 * MS <- SGSN: Identity Request IMSI (optional)
2169 * MS -> SGSN: Identity Response IMSI (optional)
2170 * MS <- SGSN: Identity Request IMEI
2171 * MS -> SGSN: Attach Request (2nd)
2172 * MS <- SGSN: Identity Response IMEI
2173 * MS <- SGSN: Attach Accept
2174 * MS -> SGSN: Attach Complete
2175 */
2176 var BSSGP_ConnHdlr vc_conn;
2177 f_init();
2178 f_sleep(1.0);
2179 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2180 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2181 vc_conn.done;
2182}
2183
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002184private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
2185 var BssgpDecoded bd;
2186 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2187
2188 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2189
2190 /* send Attach Request */
2191 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2192 * 3G auth vectors */
2193 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2194 /* The thing is, if the solSACapability is 'omit', then the
2195 * revisionLevelIndicatior is at the wrong place! */
2196 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2197 f_send_l3_gmm_llc(attach_req);
2198
2199 /* do the auth */
2200 var PDU_L3_MS_SGSN l3_mo;
2201 var PDU_L3_SGSN_MS l3_mt;
2202 var default di := activate(as_mm_identity());
2203
2204 var GSUP_IE auth_tuple;
2205 var template AuthenticationParameterAUTNTLV autn;
2206
2207 g_pars.vec := f_gen_auth_vec_3g();
2208 autn := {
2209 elementIdentifier := '28'O,
2210 lengthIndicator := lengthof(g_pars.vec.autn),
2211 autnValue := g_pars.vec.autn
2212 };
2213 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2214 g_pars.vec.sres,
2215 g_pars.vec.kc,
2216 g_pars.vec.ik,
2217 g_pars.vec.ck,
2218 g_pars.vec.autn,
2219 g_pars.vec.res));
2220 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2221 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2222 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2223
2224 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2225 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2226 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2227
2228 /* send the gmm auth failure with resync IE */
2229 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2230
2231 /* wait for the GSUP resync request */
2232 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2233 g_pars.imsi,
2234 g_pars.vec.auts,
2235 g_pars.vec.rand));
2236
2237 /* generate new key material */
2238 g_pars.vec := f_gen_auth_vec_3g();
2239 autn := {
2240 elementIdentifier := '28'O,
2241 lengthIndicator := lengthof(g_pars.vec.autn),
2242 autnValue := g_pars.vec.autn
2243 };
2244
2245 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2246 g_pars.vec.sres,
2247 g_pars.vec.kc,
2248 g_pars.vec.ik,
2249 g_pars.vec.ck,
2250 g_pars.vec.autn,
2251 g_pars.vec.res));
2252 /* send new key material */
2253 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2254
2255 /* wait for the new Auth Request */
2256 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2257 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2258 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2259 l3_mt := bd.l3_mt;
2260 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2261 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2262 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2263 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2264 valueField := substr(g_pars.vec.res, 0, 4)
2265 };
2266 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2267 elementIdentifier := '21'O,
2268 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2269 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2270 };
2271 l3_mo := valueof(auth_ciph_resp);
2272 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2273 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2274 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2275 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2276 }
2277 f_send_l3_gmm_llc(l3_mo);
2278 deactivate(di);
2279
2280 /* Expect SGSN to perform LU with HLR */
2281 f_gmm_gsup_lu_isd();
2282
2283 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2284 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2285 }
2286 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2287 setverdict(pass);
2288}
2289
2290testcase TC_attach_usim_resync() runs on test_CT {
2291 /* MS -> SGSN: Attach Request
2292 * MS <- SGSN: Identity Request IMSI
2293 * MS -> SGSN: Identity Response IMSI
2294 * MS <- SGSN: Identity Request IMEI
2295 * MS -> SGSN: Identity Response IMEI
2296 * HLR<- SGSN: SAI Request
2297 * HLR-> SGSN: SAI Response
2298 * MS <- SGSN: Auth Request
2299 * MS -> SGSN: Auth Failure (with AUTS)
2300 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2301 * HLR-> SGSN: SAI Response (new key material)
2302 * MS <- SGSN: Auth Request (new key material)
2303 * MS -> SGSN: Auth Response
2304 * MS <- SGSN: Attach Accept
2305 * MS -> SGSN: Attach Complete
2306 */
2307 var BSSGP_ConnHdlr vc_conn;
2308 f_init();
2309 f_sleep(1.0);
2310 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2311 vc_conn.done;
2312}
2313
Harald Weltea05b8072019-04-23 22:35:05 +02002314
2315/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2316private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2317 f_gmm_attach(false, false);
2318 f_sleep(1.0);
2319 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2320 /* try to detach to check if SGSN is still alive */
2321 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2322}
2323testcase TC_llc_null() runs on test_CT {
2324 var BSSGP_ConnHdlr vc_conn;
2325 f_init();
2326 f_sleep(1.0);
2327 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2328 vc_conn.done;
2329}
2330
Harald Welte645a1512019-04-23 23:18:23 +02002331/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2332private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2333 f_gmm_attach(false, false);
2334 f_sleep(1.0);
2335 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2336 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP)));
2337 setverdict(pass);
2338}
2339testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2340 var BSSGP_ConnHdlr vc_conn;
2341 f_init();
2342 f_sleep(1.0);
2343 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2344 vc_conn.done;
2345}
2346
2347/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2348private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2349 f_gmm_attach(false, false);
2350 f_sleep(1.0);
2351 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
2352 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP)));
2353 setverdict(pass);
2354}
2355testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2356 var BSSGP_ConnHdlr vc_conn;
2357 f_init();
2358 f_sleep(1.0);
2359 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2360 vc_conn.done;
2361}
2362
Harald Welte2aaac1b2019-05-02 10:02:53 +02002363/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2364private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2365 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2366 var template (value) XID_Information xid;
2367 var template XID_Information xid_rx;
2368
2369 /* first perform regular attach */
2370 f_TC_attach(id);
2371 /* then activate PDP context */
2372 f_pdp_ctx_act(apars);
2373
2374 /* start MO XID */
2375 xid := { ts_XID_L3(''O) };
2376 xid_rx := { tr_XID_L3(''O) };
2377 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2378 alt {
2379 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(xid_rx, apars.sapi)));
2380 [] as_xid(apars);
2381 }
2382 setverdict(pass);
2383}
2384testcase TC_xid_empty_l3() runs on test_CT {
2385 var BSSGP_ConnHdlr vc_conn;
2386 f_init();
2387 f_sleep(1.0);
2388 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2389 vc_conn.done;
2390}
2391
2392private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2393 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2394 var template (value) XID_Information xid;
2395 var template XID_Information xid_rx;
2396
2397 /* first perform regular attach */
2398 f_TC_attach(id);
2399 /* then activate PDP context */
2400 f_pdp_ctx_act(apars);
2401
2402 /* start MO XID */
2403 xid := { ts_XID_N201U(1234) };
2404 xid_rx := { tr_XID_N201U(1234) };
2405 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2406 alt {
2407 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi)));
2408 [] as_xid(apars);
2409 }
2410 setverdict(pass);
2411}
2412testcase TC_xid_n201u() runs on test_CT {
2413 var BSSGP_ConnHdlr vc_conn;
2414 f_init();
2415 f_sleep(1.0);
2416 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2417 vc_conn.done;
2418}
2419
Alexander Couzens6bee0872019-05-11 01:48:50 +02002420private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2421 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2422
2423 /* first perform regular attach */
2424 f_TC_attach(id);
2425 /* then activate PDP context */
2426 f_pdp_ctx_act(apars);
2427 /* do a normal detach */
2428 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2429}
2430
2431testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2432 /* MS -> SGSN: Attach Request
2433 * MS <-> SGSN: [..]
2434 * MS -> SGSN: Attach Complete
2435 * MS -> SGSN: PDP Activate Request
2436 * MS <- SGSN: PDP Activate Accept
2437 * MS -> SGSN: GMM Detach Request
2438 * MS <- SGSN: GMM Detach Accept
2439 */
2440 var BSSGP_ConnHdlr vc_conn;
2441 f_init();
2442 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2443 vc_conn.done;
2444}
Harald Welte645a1512019-04-23 23:18:23 +02002445
2446
Harald Welte5ac31492018-02-15 20:39:13 +01002447control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002448 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002449 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002450 execute( TC_attach_umts_aka_umts_res() );
2451 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002452 execute( TC_attach_auth_id_timeout() );
2453 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002454 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002455 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002456 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002457 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002458 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002459 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002460 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002461 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002462 execute( TC_attach_closed_add_vty(), 20.0 );
2463 execute( TC_attach_check_subscriber_list(), 20.0 );
2464 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002465 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002466 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2467 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2468 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2469 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002470 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002471 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002472 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002473 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002474 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002475 execute( TC_detach_unknown_nopoweroff() );
2476 execute( TC_detach_unknown_poweroff() );
2477 execute( TC_detach_nopoweroff() );
2478 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002479 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002480 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002481 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002482 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002483 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002484 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002485 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002486 execute( TC_attach_restart_ctr_echo() );
2487 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002488 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002489 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2490 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002491 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002492 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002493 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002494
Harald Welte2aaac1b2019-05-02 10:02:53 +02002495 execute( TC_xid_empty_l3() );
2496 execute( TC_xid_n201u() );
2497
Harald Weltea05b8072019-04-23 22:35:05 +02002498 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002499 execute( TC_llc_sabm_dm_llgmm() );
2500 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002501}
Harald Welte96a33b02018-02-04 10:36:22 +01002502
2503
2504
2505}