blob: e3497197c61334ea28fa131bd6c1c7cba7148dcd [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 Welte955aa942019-05-03 01:29:29 +0200404 [] BSSGP[gb_idx].receive(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 Welte955aa942019-05-03 01:29:29 +0200409 [] BSSGP[gb_idx].receive(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 {
Harald Welteca362462019-05-02 20:11:21 +0200419 var PDU_L3_SGSN_MS l3_mt;
420 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200421 [] BSSGP[gb_idx].receive(rx_tpl) -> value l3_mt { }
Harald Welteca362462019-05-02 20:11:21 +0200422 }
423 return l3_mt;
424}
425
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200426/* perform GMM authentication (if expected).
427 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
428 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200429function 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 +0100430 var PDU_L3_MS_SGSN l3_mo;
431 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200432 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100433 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200434 var GSUP_IE auth_tuple;
435 var template AuthenticationParameterAUTNTLV autn;
436
437 if (umts_aka_challenge) {
438 g_pars.vec := f_gen_auth_vec_3g();
439 autn := {
440 elementIdentifier := '28'O,
441 lengthIndicator := lengthof(g_pars.vec.autn),
442 autnValue := g_pars.vec.autn
443 };
444
445 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
446 g_pars.vec.sres,
447 g_pars.vec.kc,
448 g_pars.vec.ik,
449 g_pars.vec.ck,
450 g_pars.vec.autn,
451 g_pars.vec.res));
452 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
453 } else {
454 g_pars.vec := f_gen_auth_vec_2g();
455 autn := omit;
456 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
457 g_pars.vec.sres,
458 g_pars.vec.kc));
459 log("GSUP sends only 2G auth tuple", auth_tuple);
460 }
Harald Welteca362462019-05-02 20:11:21 +0200461
Harald Welte5ac31492018-02-15 20:39:13 +0100462 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
463 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200464
465 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
466 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200467 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100468 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200469 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
470
471 if (umts_aka_challenge and not force_gsm_sres) {
472 /* set UMTS response instead */
473 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
474 valueField := substr(g_pars.vec.res, 0, 4)
475 };
476 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
477 elementIdentifier := '21'O,
478 lengthIndicator := lengthof(g_pars.vec.res) - 4,
479 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
480 };
481 }
482
483 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100484 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
485 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
486 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
487 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
488 }
Harald Welteca362462019-05-02 20:11:21 +0200489 f_send_l3_gmm_llc(l3_mo, gb_idx);
Harald Welte76dee092018-02-16 22:12:59 +0100490 } else {
491 /* wait for identity procedure */
492 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100493 }
Harald Welte76dee092018-02-16 22:12:59 +0100494
Harald Welte5ac31492018-02-15 20:39:13 +0100495 deactivate(di);
496}
497
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200498function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100499 g_pars.p_tmsi := p_tmsi;
500 /* update TLLI */
501 g_pars.tlli_old := g_pars.tlli;
502 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200503 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100504}
505
Harald Welte04683d02018-02-16 22:43:45 +0100506function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
507 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100508 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200509 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100510 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200511 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200512 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100513 }
Harald Welte04683d02018-02-16 22:43:45 +0100514 g_pars.ra := aa.routingAreaIdentification;
515 if (ispresent(aa.allocatedPTMSI)) {
516 if (not g_pars.net.expect_ptmsi) {
517 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200518 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100519 }
Harald Weltef70997d2018-02-17 10:11:19 +0100520 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100521 }
522 if (ispresent(aa.msIdentity)) {
523 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200524 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100525 }
526 /* P-TMSI.sig */
527 if (ispresent(aa.ptmsiSignature)) {
528 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
529 }
530 /* updateTimer */
531 // aa.readyTimer
532 /* T3302, T3319, T3323, T3312_ext, T3324 */
533}
534
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200535function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100536 /* mandatory IE */
537 g_pars.ra := ra.routingAreaId;
538 if (ispresent(ra.allocatedPTMSI)) {
539 if (not g_pars.net.expect_ptmsi) {
540 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200541 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100542 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200543 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100544 }
545 if (ispresent(ra.msIdentity)) {
546 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200547 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100548 }
549 /* P-TMSI.sig */
550 if (ispresent(ra.ptmsiSignature)) {
551 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
552 }
553 /* updateTimer */
554 // aa.readyTimer
555 /* T3302, T3319, T3323, T3312_ext, T3324 */
556}
557
558
Harald Welte5a4fa042018-02-16 20:59:21 +0100559function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
560 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
561}
562
Harald Welte23178c52018-02-17 09:36:33 +0100563/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100564private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100565 if (ispresent(g_pars.p_tmsi)) {
566 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
567 } else {
568 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
569 }
570}
571
Harald Welte311ec272018-02-17 09:40:03 +0100572private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100573 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100574 /* Expect MSC to perform LU with HLR */
575 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100576 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
577 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
578 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100579 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
580 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
581}
582
Harald Welteca362462019-05-02 20:11:21 +0200583friend 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 +0100584 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200585 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 +0200586 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100587
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200588 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
589 * 3G auth vectors */
590 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
591 /* The thing is, if the solSACapability is 'omit', then the
592 * revisionLevelIndicatior is at the wrong place! */
593 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
594
Harald Welteca362462019-05-02 20:11:21 +0200595 f_send_l3_gmm_llc(attach_req, gb_idx);
596 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200597 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100598 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100599
Harald Welteca362462019-05-02 20:11:21 +0200600 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
601 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
602
Harald Welte04683d02018-02-16 22:43:45 +0100603 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welteca362462019-05-02 20:11:21 +0200604 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL, gb_idx);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200605}
606
607private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
608 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100609 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100610}
611
612testcase TC_attach() runs on test_CT {
613 var BSSGP_ConnHdlr vc_conn;
614 f_init();
615 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200616 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100617 vc_conn.done;
618}
619
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100620testcase TC_attach_mnc3() runs on test_CT {
621 var BSSGP_ConnHdlr vc_conn;
622 f_init('023042'H);
623 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200624 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100625 vc_conn.done;
626}
627
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200628private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
629 f_gmm_attach(true, false);
630 setverdict(pass);
631}
632testcase TC_attach_umts_aka_umts_res() runs on test_CT {
633 var BSSGP_ConnHdlr vc_conn;
634 f_init();
635 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200636 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200637 vc_conn.done;
638}
639
640private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
641 f_gmm_attach(true, true);
642 setverdict(pass);
643}
644testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
645 var BSSGP_ConnHdlr vc_conn;
646 f_init();
647 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200648 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200649 vc_conn.done;
650}
651
Harald Welte5b7c8122018-02-16 21:48:17 +0100652/* MS never responds to ID REQ, expect ATTACH REJECT */
653private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100654 var RoutingAreaIdentificationV old_ra := f_random_RAI();
655
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200656 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 +0100657 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200658 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100659 /* don't send ID Response */
660 repeat;
661 }
Harald Welte955aa942019-05-03 01:29:29 +0200662 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100663 setverdict(pass);
664 }
Harald Welte955aa942019-05-03 01:29:29 +0200665 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100666 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200667 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100668 }
669 }
670}
671testcase TC_attach_auth_id_timeout() runs on test_CT {
672 var BSSGP_ConnHdlr vc_conn;
673 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200674 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 +0100675 vc_conn.done;
676}
677
678/* HLR never responds to SAI REQ, expect ATTACH REJECT */
679private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100680 var RoutingAreaIdentificationV old_ra := f_random_RAI();
681
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200682 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 +0100683 alt {
684 [] as_mm_identity();
685 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
686 }
687 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200688 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100689 setverdict(pass);
690}
691testcase TC_attach_auth_sai_timeout() runs on test_CT {
692 var BSSGP_ConnHdlr vc_conn;
693 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200694 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100695 vc_conn.done;
696}
697
Harald Weltefe253882018-02-17 09:25:00 +0100698/* HLR rejects SAI, expect ATTACH REJECT */
699private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100700 var RoutingAreaIdentificationV old_ra := f_random_RAI();
701
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200702 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 +0100703 alt {
704 [] as_mm_identity();
705 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
706 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
707 }
708 }
Harald Welte955aa942019-05-03 01:29:29 +0200709 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100710 setverdict(pass);
711}
712testcase TC_attach_auth_sai_reject() runs on test_CT {
713 var BSSGP_ConnHdlr vc_conn;
714 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200715 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100716 vc_conn.done;
717}
718
Harald Welte5b7c8122018-02-16 21:48:17 +0100719/* HLR never responds to UL REQ, expect ATTACH REJECT */
720private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200721 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100722 var RoutingAreaIdentificationV old_ra := f_random_RAI();
723
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200724 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 +0100725 f_gmm_auth();
726 /* Expect MSC to perform LU with HLR */
727 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
728 /* Never follow-up with ISD_REQ or UL_RES */
729 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200730 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100731 setverdict(pass);
732 }
Harald Welte955aa942019-05-03 01:29:29 +0200733 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
734 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100735 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200736 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100737 }
738 }
739}
740testcase TC_attach_gsup_lu_timeout() runs on test_CT {
741 var BSSGP_ConnHdlr vc_conn;
742 f_init();
743 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200744 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100745 vc_conn.done;
746}
747
Harald Welteb7c14e92018-02-17 09:29:16 +0100748/* HLR rejects UL REQ, expect ATTACH REJECT */
749private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200750 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100751 var RoutingAreaIdentificationV old_ra := f_random_RAI();
752
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200753 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 +0100754 f_gmm_auth();
755 /* Expect MSC to perform LU with HLR */
756 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
757 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
758 }
759 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200760 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100761 setverdict(pass);
762 }
Harald Welte955aa942019-05-03 01:29:29 +0200763 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
764 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100765 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200766 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100767 }
768 }
769}
770testcase TC_attach_gsup_lu_reject() runs on test_CT {
771 var BSSGP_ConnHdlr vc_conn;
772 f_init();
773 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200774 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100775 vc_conn.done;
776}
777
778
Harald Welte3823e2e2018-02-16 21:53:48 +0100779/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
780private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200781 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100782 var RoutingAreaIdentificationV old_ra := f_random_RAI();
783
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200784 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 +0100785 f_gmm_auth();
786 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100787 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100788
Harald Welte955aa942019-05-03 01:29:29 +0200789 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
790 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100791 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200792 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100793 setverdict(pass);
794}
Harald Welte3823e2e2018-02-16 21:53:48 +0100795testcase TC_attach_combined() runs on test_CT {
796 var BSSGP_ConnHdlr vc_conn;
797 f_init();
798 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200799 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100800 vc_conn.done;
801}
802
Harald Welte76dee092018-02-16 22:12:59 +0100803/* Attempt of GPRS ATTACH in 'accept all' mode */
804private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200805 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +0100806 var RoutingAreaIdentificationV old_ra := f_random_RAI();
807
808 g_pars.net.expect_auth := false;
809
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200810 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 +0100811 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +0200812 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
813 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100814 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200815 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100816 setverdict(pass);
817}
818testcase TC_attach_accept_all() runs on test_CT {
819 var BSSGP_ConnHdlr vc_conn;
820 f_init();
821 f_sleep(1.0);
822 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200823 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100824 vc_conn.done;
825}
Harald Welte5b7c8122018-02-16 21:48:17 +0100826
Harald Welteb2124b22018-02-16 22:26:56 +0100827/* Attempt of GPRS ATTACH in 'accept all' mode */
828private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100829 var RoutingAreaIdentificationV old_ra := f_random_RAI();
830
831 /* Simulate a foreign IMSI */
832 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200833 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100834
835 g_pars.net.expect_auth := false;
836
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200837 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 +0100838 alt {
839 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +0200840 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +0100841 setverdict(pass);
842 }
Harald Welte955aa942019-05-03 01:29:29 +0200843 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +0100844 setverdict(pass);
845 }
Harald Welte955aa942019-05-03 01:29:29 +0200846 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200847 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200848 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200849 }
Harald Welteb2124b22018-02-16 22:26:56 +0100850 }
851}
852testcase TC_attach_closed() runs on test_CT {
853 var BSSGP_ConnHdlr vc_conn;
854 f_init();
855 f_sleep(1.0);
856 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
857 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200858 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100859 vc_conn.done;
860 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200861 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100862 vc_conn.done;
863}
864
Harald Welte04683d02018-02-16 22:43:45 +0100865/* Routing Area Update from Unknown TLLI -> REJECT */
866private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100867 var RoutingAreaIdentificationV old_ra := f_random_RAI();
868
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200869 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 +0100870 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200871 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
Harald Welte04683d02018-02-16 22:43:45 +0100872 setverdict(pass);
873 }
874 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200875 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100876 }
877}
878testcase TC_rau_unknown() runs on test_CT {
879 var BSSGP_ConnHdlr vc_conn;
880 f_init();
881 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200882 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100883 vc_conn.done;
884}
885
Harald Welte91636de2018-02-17 10:16:14 +0100886private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100887 /* first perform regular attach */
888 f_TC_attach(id);
889
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200890 f_routing_area_update(g_pars.ra);
891
Harald Welte91636de2018-02-17 10:16:14 +0100892}
893testcase TC_attach_rau() runs on test_CT {
894 var BSSGP_ConnHdlr vc_conn;
895 f_init();
896 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200897 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100898 vc_conn.done;
899}
Harald Welte04683d02018-02-16 22:43:45 +0100900
Harald Welte6abb9fe2018-02-17 15:24:48 +0100901/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200902function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200903 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100904 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200905 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100906 if (expect_purge) {
907 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
908 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
909 }
910 T.start;
911 alt {
912 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
913 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200914 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100915 }
Harald Welte955aa942019-05-03 01:29:29 +0200916 [power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100917 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +0200918 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200919 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100920 /* TODO: check if any PDP contexts are deactivated on network side? */
921 }
922 [power_off] T.timeout {
923 setverdict(pass);
924 }
Harald Welte955aa942019-05-03 01:29:29 +0200925 [not power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100926 g_pars.ra := omit;
927 setverdict(pass);
928 /* TODO: check if any PDP contexts are deactivated on network side? */
929 }
Harald Welte955aa942019-05-03 01:29:29 +0200930 [] BSSGP[bssgp_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +0200931 if (power_off) {
932 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
933 } else {
934 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
935 }
936 mtc.stop;
937 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200938 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100939 }
940}
941
942/* IMSI DETACH (non-power-off) for unknown TLLI */
943private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
944 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
945}
946testcase TC_detach_unknown_nopoweroff() runs on test_CT {
947 var BSSGP_ConnHdlr vc_conn;
948 f_init();
949 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200950 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100951 vc_conn.done;
952}
953
954/* IMSI DETACH (power-off) for unknown TLLI */
955private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
956 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
957}
958testcase TC_detach_unknown_poweroff() runs on test_CT {
959 var BSSGP_ConnHdlr vc_conn;
960 f_init();
961 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200962 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100963 vc_conn.done;
964}
965
966/* IMSI DETACH (non-power-off) for known TLLI */
967private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
968 /* first perform regular attach */
969 f_TC_attach(id);
970
971 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
972}
973testcase TC_detach_nopoweroff() runs on test_CT {
974 var BSSGP_ConnHdlr vc_conn;
975 f_init();
976 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200977 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100978 vc_conn.done;
979}
980
981/* IMSI DETACH (power-off) for known TLLI */
982private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
983 /* first perform regular attach */
984 f_TC_attach(id);
985
986 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
987}
988testcase TC_detach_poweroff() runs on test_CT {
989 var BSSGP_ConnHdlr vc_conn;
990 f_init();
991 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200992 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100993 vc_conn.done;
994}
995
Harald Welteeded9ad2018-02-17 20:57:34 +0100996type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100997 BIT3 tid, /* L3 Transaction ID */
998 BIT4 nsapi, /* SNDCP NSAPI */
999 BIT4 sapi, /* LLC SAPI */
1000 QoSV qos, /* QoS parameters */
1001 PDPAddressV addr, /* IP address */
1002 octetstring apn optional, /* APN name */
1003 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1004 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001005 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001006 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001007
Harald Welte822f9102018-02-18 20:39:06 +01001008 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1009 OCT4 ggsn_tei_u, /* GGSN TEI User */
1010 octetstring ggsn_ip_c, /* GGSN IP Control */
1011 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001012 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001013
Harald Welte822f9102018-02-18 20:39:06 +01001014 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1015 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1016 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1017 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001018};
1019
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001020
1021private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1022 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1023 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1024 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1025 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1026 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1027 f_gtp_register_teid(apars.ggsn_tei_c);
1028 f_gtp_register_teid(apars.ggsn_tei_u);
1029}
1030
Harald Weltef7191672019-05-02 20:37:23 +02001031function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1032runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001033 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1034 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001035 var template Recovery_gtpc recovery := omit;
1036
1037 if (send_recovery) {
1038 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1039 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001040
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001041 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 +02001042 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001043 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1044 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1045 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1046 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1047 apars.sgsn_tei_c, apars.gtp_resp_cause,
1048 apars.ggsn_tei_c, apars.ggsn_tei_u,
1049 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001050 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1051 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001052 }
1053 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001054 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001055 setverdict(pass);
1056 }
Harald Welte955aa942019-05-03 01:29:29 +02001057 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001058 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001059 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001060 }
Harald Welte955aa942019-05-03 01:29:29 +02001061 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001062 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001063 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001064 }
Harald Welte955aa942019-05-03 01:29:29 +02001065 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001066 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1067 mtc.stop;
1068 }
Harald Welte955aa942019-05-03 01:29:29 +02001069 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001070 setverdict(pass);
1071 }
Harald Weltef7191672019-05-02 20:37:23 +02001072 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001073 }
1074}
1075
Harald Weltef7191672019-05-02 20:37:23 +02001076function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1077runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001078 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1079 var Gtp1cUnitdata g_ud;
1080
Harald Weltef7191672019-05-02 20:37:23 +02001081 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 +01001082 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1083 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001084 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001085 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1086 }
1087 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001088 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001089 setverdict(pass);
1090 }
Harald Weltef7191672019-05-02 20:37:23 +02001091 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001092 }
1093}
1094
Harald Weltef7191672019-05-02 20:37:23 +02001095function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1096runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001097 var Gtp1cUnitdata g_ud;
1098 var integer seq_nr := 23;
1099 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1100
Harald Weltef7191672019-05-02 20:37:23 +02001101 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001102 if (error_ind) {
1103 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1104 } else {
1105 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1106 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001107
1108 timer T := 5.0;
1109 T.start;
1110
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001111 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001112 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Harald Weltef7191672019-05-02 20:37:23 +02001113 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001114 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001115 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1116 repeat;
1117 }
1118 [] T.timeout {
1119 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1120 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001121 }
1122}
1123
Harald Welte6f203162018-02-18 22:04:55 +01001124
Harald Welteeded9ad2018-02-17 20:57:34 +01001125/* Table 10.5.156/3GPP TS 24.008 */
1126template (value) QoSV t_QosDefault := {
1127 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1128 delayClass := '100'B, /* best effort */
1129 spare1 := '00'B,
1130 precedenceClass := '010'B, /* normal */
1131 spare2 := '0'B,
1132 peakThroughput := '0000'B, /* subscribed */
1133 meanThroughput := '00000'B, /* subscribed */
1134 spare3 := '000'B,
1135 deliverErroneusSDU := omit,
1136 deliveryOrder := omit,
1137 trafficClass := omit,
1138 maxSDUSize := omit,
1139 maxBitrateUplink := omit,
1140 maxBitrateDownlink := omit,
1141 sduErrorRatio := omit,
1142 residualBER := omit,
1143 trafficHandlingPriority := omit,
1144 transferDelay := omit,
1145 guaranteedBitRateUplink := omit,
1146 guaranteedBitRateDownlink := omit,
1147 sourceStatisticsDescriptor := omit,
1148 signallingIndication := omit,
1149 spare4 := omit,
1150 maxBitrateDownlinkExt := omit,
1151 guaranteedBitRateDownlinkExt := omit,
1152 maxBitrateUplinkExt := omit,
1153 guaranteedBitRateUplinkExt := omit,
1154 maxBitrateDownlinkExt2 := omit,
1155 guaranteedBitRateDownlinkExt2 := omit,
1156 maxBitrateUplinkExt2 := omit,
1157 guaranteedBitRateUplinkExt2 := omit
1158}
1159
1160/* 10.5.6.4 / 3GPP TS 24.008 */
1161template (value) PDPAddressV t_AddrIPv4dyn := {
1162 pdpTypeOrg := '0001'B, /* IETF */
1163 spare := '0000'B,
1164 pdpTypeNum := '21'O, /* IPv4 */
1165 addressInfo := omit
1166}
1167template (value) PDPAddressV t_AddrIPv6dyn := {
1168 pdpTypeOrg := '0001'B, /* IETF */
1169 spare := '0000'B,
1170 pdpTypeNum := '53'O, /* IPv6 */
1171 addressInfo := omit
1172}
1173
Harald Welte37692d82018-02-18 15:21:34 +01001174template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001175 tid := '000'B,
1176 nsapi := '0101'B, /* < 5 are reserved */
1177 sapi := '0011'B, /* 3/5/9/11 */
1178 qos := t_QosDefault,
1179 addr := t_AddrIPv4dyn,
1180 apn := omit,
1181 pco := omit,
1182 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001183 gtp_resp_cause := int2oct(128, 1),
1184 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001185
1186 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001187 ggsn_tei_c := f_rnd_octstring(4),
1188 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001189 ggsn_ip_c := f_inet_addr(ggsn_ip),
1190 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001191 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001192
Harald Welteeded9ad2018-02-17 20:57:34 +01001193 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001194 sgsn_tei_u := omit,
1195 sgsn_ip_c := omit,
1196 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001197}
1198
Harald Welte37692d82018-02-18 15:21:34 +01001199template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1200 connId := 1,
1201 remName := f_inet_ntoa(ip),
1202 remPort := GTP1U_PORT
1203}
1204
1205template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1206 connId := 1,
1207 remName := f_inet_ntoa(ip),
1208 remPort := GTP1C_PORT
1209}
1210
1211private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1212 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1213 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1214}
1215
Harald Weltef7191672019-05-02 20:37:23 +02001216private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001217 [] BSSGP[gb_idx].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001218 repeat;
1219 }
1220}
1221
1222template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1223 pDU_SN_UNITDATA := {
1224 nsapi := nsapi,
1225 moreBit := ?,
1226 snPduType := '1'B,
1227 firstSegmentIndicator := ?,
1228 spareBit := ?,
1229 pcomp := ?,
1230 dcomp := ?,
1231 npduNumber := ?,
1232 segmentNumber := ?,
1233 npduNumberContinued := ?,
1234 dataSegmentSnUnitdataPdu := payload
1235 }
1236}
1237
1238/* simple case: single segment, no compression */
1239template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1240 pDU_SN_UNITDATA := {
1241 nsapi := nsapi,
1242 moreBit := '0'B,
1243 snPduType := '1'B,
1244 firstSegmentIndicator := '1'B,
1245 spareBit := '0'B,
1246 pcomp := '0000'B,
1247 dcomp := '0000'B,
1248 npduNumber := '0000'B,
1249 segmentNumber := '0000'B,
1250 npduNumberContinued := '00'O,
1251 dataSegmentSnUnitdataPdu := payload
1252 }
1253}
1254
1255/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001256private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1257runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001258 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1259 f_gtpu_send(apars, payload);
1260 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1261 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001262 [] as_xid(apars, gb_idx);
Harald Welte955aa942019-05-03 01:29:29 +02001263 //[] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1264 [] BSSGP[gb_idx].receive(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? */
Harald Welte955aa942019-05-03 01:29:29 +02001303 [] BSSGP[0].receive(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 }
Harald Welte955aa942019-05-03 01:29:29 +02001310 [] BSSGP[0].receive(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 {
Harald Welte955aa942019-05-03 01:29:29 +02001446 [] BSSGP[0].receive(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 {
Harald Welte955aa942019-05-03 01:29:29 +02001521 [] BSSGP[0].receive(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 }
Harald Welte955aa942019-05-03 01:29:29 +02001566 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001567
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 {
Harald Welte955aa942019-05-03 01:29:29 +02001582 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001583 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 {
Harald Welte955aa942019-05-03 01:29:29 +02001613 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001614 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 {
Harald Welte955aa942019-05-03 01:29:29 +02001668 [] BSSGP[0].receive(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 */
Harald Welte955aa942019-05-03 01:29:29 +02001727 BSSGP[0].receive(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 {
Harald Welte955aa942019-05-03 01:29:29 +02001822 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001823 /* break */
1824 }
Harald Welte955aa942019-05-03 01:29:29 +02001825 [] BSSGP[0].receive(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 }
Harald Welte955aa942019-05-03 01:29:29 +02001830 [] BSSGP[0].receive(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 {
Harald Welte955aa942019-05-03 01:29:29 +02001870 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001871 /* break */
1872 }
Harald Welte955aa942019-05-03 01:29:29 +02001873 [] BSSGP[0].receive(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 }
Harald Welte955aa942019-05-03 01:29:29 +02001878 [] BSSGP[0].receive(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();
Harald Welte955aa942019-05-03 01:29:29 +02001930 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02001931
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 {
Harald Welte955aa942019-05-03 01:29:29 +02001944 [] BSSGP[0].receive(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 }
Harald Welte955aa942019-05-03 01:29:29 +02001948 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
1949 f_process_attach_accept(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 }
Harald Welte955aa942019-05-03 01:29:29 +02002003 [] BSSGP[0].receive(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 {
Harald Welte955aa942019-05-03 01:29:29 +02002031 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002032
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 {
Harald Welte955aa942019-05-03 01:29:29 +02002036 [] BSSGP[bssgp].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2037 f_process_rau_accept(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 }
Harald Welte955aa942019-05-03 01:29:29 +02002041 [] BSSGP[bssgp].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002042 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 {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002050 /* first perform regular attach */
2051 f_TC_attach(id);
2052
2053 /* then send RAU */
2054 f_routing_area_update(g_pars.ra);
2055
2056 /* do another RAU */
2057 f_routing_area_update(g_pars.ra);
2058
2059 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2060}
2061
2062testcase TC_attach_rau_a_a() runs on test_CT {
2063 /* MS <-> SGSN: Successful Attach
2064 * MS -> SGSN: Routing Area Update Request
2065 * MS <- SGSN: Routing Area Update Accept
2066 * MS -> SGSN: Routing Area Update Request
2067 * MS <- SGSN: Routing Area Update Accept
2068 * MS -> SGSN: Detach (PowerOff)
2069 */
2070 var BSSGP_ConnHdlr vc_conn;
2071 f_init();
2072 f_sleep(1.0);
2073 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2074 vc_conn.done;
2075}
2076
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002077private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002078 f_TC_attach(id);
2079
2080 log("attach complete sending rau");
2081 f_routing_area_update(g_pars.ra, 0);
2082
2083 log("rau complete unregistering");
2084 f_bssgp_client_unregister(g_pars.imsi);
2085 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2086
2087 log("sending second RAU via different RA");
2088 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2089
2090 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2091}
2092
2093testcase TC_attach_rau_a_b() runs on test_CT {
2094 /* MS <-> SGSN: Successful Attach
2095 * MS -> SGSN: Routing Area _a_ Update Request
2096 * MS <- SGSN: Routing Area _a_ Update Accept
2097 * MS -> SGSN: Routing Area _b_ Update Request
2098 * MS <- SGSN: Routing Area _b_ Update Accept
2099 * MS -> SGSN: Detach (PowerOff)
2100 */
2101 var BSSGP_ConnHdlr vc_conn;
2102 f_init();
2103 f_sleep(1.0);
2104 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2105 vc_conn.done;
2106}
2107
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002108private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2109 var integer count_req := 0;
2110 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2111 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002112 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002113
2114 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2115
2116 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002117 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002118 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2119 mtc.stop;
2120 }
Harald Welte955aa942019-05-03 01:29:29 +02002121 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002122 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2123 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2124 repeat;
2125 }
Harald Welte955aa942019-05-03 01:29:29 +02002126 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002127 /* send out a second GMM_Attach Request.
2128 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2129 * of the same content */
2130 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2131 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
2132 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2133 }
2134 }
2135 f_sleep(1.0);
2136
2137 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2138 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002139 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002140 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2141 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2142 repeat;
2143 }
Harald Welte955aa942019-05-03 01:29:29 +02002144 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002145 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2146 mtc.stop;
2147 }
Harald Welte955aa942019-05-03 01:29:29 +02002148 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002149 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2150 mtc.stop;
2151 }
Harald Welte955aa942019-05-03 01:29:29 +02002152 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2153 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002154 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2155 setverdict(pass);
2156 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2157 }
2158 }
2159}
2160
2161testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2162 /* Testing if the SGSN ignore Attach Request with the exact same content */
2163 /* MS -> SGSN: Attach Request IMSI
2164 * MS <- SGSN: Identity Request IMSI (optional)
2165 * MS -> SGSN: Identity Response IMSI (optional)
2166 * MS <- SGSN: Identity Request IMEI
2167 * MS -> SGSN: Attach Request (2nd)
2168 * MS <- SGSN: Identity Response IMEI
2169 * MS <- SGSN: Attach Accept
2170 * MS -> SGSN: Attach Complete
2171 */
2172 var BSSGP_ConnHdlr vc_conn;
2173 f_init();
2174 f_sleep(1.0);
2175 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2176 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2177 vc_conn.done;
2178}
2179
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002180private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002181 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2182
2183 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2184
2185 /* send Attach Request */
2186 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2187 * 3G auth vectors */
2188 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2189 /* The thing is, if the solSACapability is 'omit', then the
2190 * revisionLevelIndicatior is at the wrong place! */
2191 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2192 f_send_l3_gmm_llc(attach_req);
2193
2194 /* do the auth */
2195 var PDU_L3_MS_SGSN l3_mo;
2196 var PDU_L3_SGSN_MS l3_mt;
2197 var default di := activate(as_mm_identity());
2198
2199 var GSUP_IE auth_tuple;
2200 var template AuthenticationParameterAUTNTLV autn;
2201
2202 g_pars.vec := f_gen_auth_vec_3g();
2203 autn := {
2204 elementIdentifier := '28'O,
2205 lengthIndicator := lengthof(g_pars.vec.autn),
2206 autnValue := g_pars.vec.autn
2207 };
2208 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2209 g_pars.vec.sres,
2210 g_pars.vec.kc,
2211 g_pars.vec.ik,
2212 g_pars.vec.ck,
2213 g_pars.vec.autn,
2214 g_pars.vec.res));
2215 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2216 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2217 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2218
2219 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2220 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002221 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002222
2223 /* send the gmm auth failure with resync IE */
2224 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2225
2226 /* wait for the GSUP resync request */
2227 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2228 g_pars.imsi,
2229 g_pars.vec.auts,
2230 g_pars.vec.rand));
2231
2232 /* generate new key material */
2233 g_pars.vec := f_gen_auth_vec_3g();
2234 autn := {
2235 elementIdentifier := '28'O,
2236 lengthIndicator := lengthof(g_pars.vec.autn),
2237 autnValue := g_pars.vec.autn
2238 };
2239
2240 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2241 g_pars.vec.sres,
2242 g_pars.vec.kc,
2243 g_pars.vec.ik,
2244 g_pars.vec.ck,
2245 g_pars.vec.autn,
2246 g_pars.vec.res));
2247 /* send new key material */
2248 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2249
2250 /* wait for the new Auth Request */
2251 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2252 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002253 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002254 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2255 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2256 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2257 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2258 valueField := substr(g_pars.vec.res, 0, 4)
2259 };
2260 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2261 elementIdentifier := '21'O,
2262 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2263 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2264 };
2265 l3_mo := valueof(auth_ciph_resp);
2266 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2267 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2268 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2269 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2270 }
2271 f_send_l3_gmm_llc(l3_mo);
2272 deactivate(di);
2273
2274 /* Expect SGSN to perform LU with HLR */
2275 f_gmm_gsup_lu_isd();
2276
Harald Welte955aa942019-05-03 01:29:29 +02002277 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2278 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002279 }
2280 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2281 setverdict(pass);
2282}
2283
2284testcase TC_attach_usim_resync() runs on test_CT {
2285 /* MS -> SGSN: Attach Request
2286 * MS <- SGSN: Identity Request IMSI
2287 * MS -> SGSN: Identity Response IMSI
2288 * MS <- SGSN: Identity Request IMEI
2289 * MS -> SGSN: Identity Response IMEI
2290 * HLR<- SGSN: SAI Request
2291 * HLR-> SGSN: SAI Response
2292 * MS <- SGSN: Auth Request
2293 * MS -> SGSN: Auth Failure (with AUTS)
2294 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2295 * HLR-> SGSN: SAI Response (new key material)
2296 * MS <- SGSN: Auth Request (new key material)
2297 * MS -> SGSN: Auth Response
2298 * MS <- SGSN: Attach Accept
2299 * MS -> SGSN: Attach Complete
2300 */
2301 var BSSGP_ConnHdlr vc_conn;
2302 f_init();
2303 f_sleep(1.0);
2304 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2305 vc_conn.done;
2306}
2307
Harald Weltea05b8072019-04-23 22:35:05 +02002308
2309/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2310private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2311 f_gmm_attach(false, false);
2312 f_sleep(1.0);
2313 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2314 /* try to detach to check if SGSN is still alive */
2315 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2316}
2317testcase TC_llc_null() runs on test_CT {
2318 var BSSGP_ConnHdlr vc_conn;
2319 f_init();
2320 f_sleep(1.0);
2321 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2322 vc_conn.done;
2323}
2324
Harald Welte645a1512019-04-23 23:18:23 +02002325/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2326private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2327 f_gmm_attach(false, false);
2328 f_sleep(1.0);
2329 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002330 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002331 setverdict(pass);
2332}
2333testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2334 var BSSGP_ConnHdlr vc_conn;
2335 f_init();
2336 f_sleep(1.0);
2337 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2338 vc_conn.done;
2339}
2340
2341/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2342private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2343 f_gmm_attach(false, false);
2344 f_sleep(1.0);
2345 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002346 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002347 setverdict(pass);
2348}
2349testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2350 var BSSGP_ConnHdlr vc_conn;
2351 f_init();
2352 f_sleep(1.0);
2353 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2354 vc_conn.done;
2355}
2356
Harald Welte2aaac1b2019-05-02 10:02:53 +02002357/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2358private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2359 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2360 var template (value) XID_Information xid;
2361 var template XID_Information xid_rx;
2362
2363 /* first perform regular attach */
2364 f_TC_attach(id);
2365 /* then activate PDP context */
2366 f_pdp_ctx_act(apars);
2367
2368 /* start MO XID */
2369 xid := { ts_XID_L3(''O) };
2370 xid_rx := { tr_XID_L3(''O) };
2371 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2372 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002373 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002374 [] as_xid(apars);
2375 }
2376 setverdict(pass);
2377}
2378testcase TC_xid_empty_l3() runs on test_CT {
2379 var BSSGP_ConnHdlr vc_conn;
2380 f_init();
2381 f_sleep(1.0);
2382 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2383 vc_conn.done;
2384}
2385
2386private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2387 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2388 var template (value) XID_Information xid;
2389 var template XID_Information xid_rx;
2390
2391 /* first perform regular attach */
2392 f_TC_attach(id);
2393 /* then activate PDP context */
2394 f_pdp_ctx_act(apars);
2395
2396 /* start MO XID */
2397 xid := { ts_XID_N201U(1234) };
2398 xid_rx := { tr_XID_N201U(1234) };
2399 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2400 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002401 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002402 [] as_xid(apars);
2403 }
2404 setverdict(pass);
2405}
2406testcase TC_xid_n201u() runs on test_CT {
2407 var BSSGP_ConnHdlr vc_conn;
2408 f_init();
2409 f_sleep(1.0);
2410 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2411 vc_conn.done;
2412}
2413
Alexander Couzens6bee0872019-05-11 01:48:50 +02002414private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2415 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2416
2417 /* first perform regular attach */
2418 f_TC_attach(id);
2419 /* then activate PDP context */
2420 f_pdp_ctx_act(apars);
2421 /* do a normal detach */
2422 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2423}
2424
2425testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2426 /* MS -> SGSN: Attach Request
2427 * MS <-> SGSN: [..]
2428 * MS -> SGSN: Attach Complete
2429 * MS -> SGSN: PDP Activate Request
2430 * MS <- SGSN: PDP Activate Accept
2431 * MS -> SGSN: GMM Detach Request
2432 * MS <- SGSN: GMM Detach Accept
2433 */
2434 var BSSGP_ConnHdlr vc_conn;
2435 f_init();
2436 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2437 vc_conn.done;
2438}
Harald Welte645a1512019-04-23 23:18:23 +02002439
2440
Harald Welte5ac31492018-02-15 20:39:13 +01002441control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002442 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002443 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002444 execute( TC_attach_umts_aka_umts_res() );
2445 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002446 execute( TC_attach_auth_id_timeout() );
2447 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002448 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002449 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002450 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002451 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002452 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002453 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002454 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002455 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002456 execute( TC_attach_closed_add_vty(), 20.0 );
2457 execute( TC_attach_check_subscriber_list(), 20.0 );
2458 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002459 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002460 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2461 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2462 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2463 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002464 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002465 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002466 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002467 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002468 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002469 execute( TC_detach_unknown_nopoweroff() );
2470 execute( TC_detach_unknown_poweroff() );
2471 execute( TC_detach_nopoweroff() );
2472 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002473 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002474 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002475 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002476 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002477 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002478 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002479 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002480 execute( TC_attach_restart_ctr_echo() );
2481 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002482 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002483 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2484 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002485 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002486 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002487 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002488
Harald Welte2aaac1b2019-05-02 10:02:53 +02002489 execute( TC_xid_empty_l3() );
2490 execute( TC_xid_n201u() );
2491
Harald Weltea05b8072019-04-23 22:35:05 +02002492 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002493 execute( TC_llc_sabm_dm_llgmm() );
2494 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002495}
Harald Welte96a33b02018-02-04 10:36:22 +01002496
2497
2498
2499}