blob: 5633183d1ac79fcd40b600c1f26358c0127f68af [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte96a33b02018-02-04 10:36:22 +010014import from General_Types all;
15import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010016import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010017import from NS_Types all;
18import from NS_Emulation all;
19import from BSSGP_Types all;
20import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010021import from Osmocom_Gb_Types all;
22
23import from MobileL3_CommonIE_Types all;
24import from MobileL3_GMM_SM_Types all;
25import from MobileL3_Types all;
26import from L3_Templates all;
27import from L3_Common all;
28
29import from GSUP_Emulation all;
30import from GSUP_Types all;
31import from IPA_Emulation all;
32
Harald Welteeded9ad2018-02-17 20:57:34 +010033import from GTP_Emulation all;
34import from GTP_Templates all;
35import from GTP_CodecPort all;
36import from GTPC_Types all;
37import from GTPU_Types all;
38
Harald Weltea2526a82018-02-18 19:03:36 +010039import from LLC_Types all;
40import from LLC_Templates all;
41
42import from SNDCP_Types all;
43
Harald Weltebd194722018-02-16 22:11:08 +010044import from TELNETasp_PortType all;
45import from Osmocom_VTY_Functions all;
46
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010047import from GSM_RR_Types all;
48
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020049import from MobileL3_MM_Types all;
50
Harald Welteeded9ad2018-02-17 20:57:34 +010051
Harald Welte5ac31492018-02-15 20:39:13 +010052modulepar {
53 /* IP/port on which we run our internal GSUP/HLR emulation */
54 charstring mp_hlr_ip := "127.0.0.1";
55 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010056 charstring mp_ggsn_ip := "127.0.0.2";
Alexander Couzens2c12b242018-07-31 00:30:11 +020057
Alexander Couzensf3c1b412018-08-24 00:42:51 +020058 NSConfigurations mp_nsconfig := {
59 {
60 local_udp_port := 21010,
61 local_ip := "127.0.0.1",
62 remote_udp_port := 23000,
63 remote_ip := "127.0.0.1",
64 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020065 nsei := 96,
66 role_sgsn := false,
67 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020068 },
69 {
70 local_udp_port := 21011,
71 local_ip := "127.0.0.1",
72 remote_udp_port := 23000,
73 remote_ip := "127.0.0.1",
74 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020075 nsei := 97,
76 role_sgsn := false,
77 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020078 },
79 {
80 local_udp_port := 21012,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020085 nsei := 98,
86 role_sgsn := false,
87 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020089 };
Harald Welte5ac31492018-02-15 20:39:13 +010090};
91
92type record GbInstance {
93 NS_CT vc_NS,
94 BSSGP_CT vc_BSSGP,
95 BssgpConfig cfg
96};
Harald Welte96a33b02018-02-04 10:36:22 +010097
Harald Welte2fa771f2019-05-02 20:13:53 +020098const integer NUM_GB := 3;
99type record length(NUM_GB) of GbInstance GbInstances;
100type record length(NUM_GB) of NSConfiguration NSConfigurations;
101type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200102
Harald Welte96a33b02018-02-04 10:36:22 +0100103type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200104 var GbInstances g_gb;
Harald Welte96a33b02018-02-04 10:36:22 +0100105
Harald Welte5ac31492018-02-15 20:39:13 +0100106 var GSUP_Emulation_CT vc_GSUP;
107 var IPA_Emulation_CT vc_GSUP_IPA;
108 /* only to get events from IPA underneath GSUP */
109 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100110
Harald Welteeded9ad2018-02-17 20:57:34 +0100111 var GTP_Emulation_CT vc_GTP;
112
Harald Weltebd194722018-02-16 22:11:08 +0100113 port TELNETasp_PT SGSNVTY;
114
Harald Welte96a33b02018-02-04 10:36:22 +0100115 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200116 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100117};
118
Harald Welteeded9ad2018-02-17 20:57:34 +0100119type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100120 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100121 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200122 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100123}
124
125type record SGSN_ConnHdlrNetworkPars {
126 boolean expect_ptmsi,
127 boolean expect_auth,
128 boolean expect_ciph
129};
130
131type record BSSGP_ConnHdlrPars {
132 /* IMEI of the simulated ME */
133 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200134 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100135 hexstring imsi,
136 /* MSISDN of the simulated MS (probably unused) */
137 hexstring msisdn,
138 /* P-TMSI allocated to the simulated MS */
139 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100140 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100141 /* TLLI of the simulated MS */
142 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100143 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100144 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200145 BssgpCellIds bssgp_cell_id,
Harald Welte5ac31492018-02-15 20:39:13 +0100146 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100147 SGSN_ConnHdlrNetworkPars net,
148 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100149};
150
Alexander Couzens89508702018-07-31 04:16:10 +0200151private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200152 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200153 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
154
155 var RoutingAreaIdentificationV ret := {
156 mccDigit1 := mcc_mnc[0],
157 mccDigit2 := mcc_mnc[1],
158 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200159 mncDigit3 := mcc_mnc[3],
160 mncDigit1 := mcc_mnc[4],
161 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200162 lac := int2oct(cell_id.ra_id.lai.lac, 16),
163 rac := int2oct(cell_id.ra_id.rac, 8)
164 }
165 return ret;
166};
167
Alexander Couzens51114d12018-07-31 18:41:56 +0200168private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
169 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
170 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100171 /* connect lower end of BSSGP emulation with NS upper port */
172 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
173 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
174 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
175
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200176 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100177 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
178}
179
180private function f_init_gsup(charstring id) runs on test_CT {
181 id := id & "-GSUP";
182 var GsupOps ops := {
183 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
184 };
185
186 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
187 vc_GSUP := GSUP_Emulation_CT.create(id);
188
189 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
190 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
191 /* we use this hack to get events like ASP_IPA_EVENT_UP */
192 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
193
194 vc_GSUP.start(GSUP_Emulation.main(ops, id));
195 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
196
197 /* wait for incoming connection to GSUP port before proceeding */
198 timer T := 10.0;
199 T.start;
200 alt {
201 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
202 [] T.timeout {
203 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200204 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100205 }
206 }
207}
208
Harald Welteeded9ad2018-02-17 20:57:34 +0100209private function f_init_gtp(charstring id) runs on test_CT {
210 id := id & "-GTP";
211
212 var GtpEmulationCfg gtp_cfg := {
213 gtpc_bind_ip := mp_ggsn_ip,
214 gtpc_bind_port := GTP1C_PORT,
215 gtpu_bind_ip := mp_ggsn_ip,
216 gtpu_bind_port := GTP1U_PORT,
217 sgsn_role := false
218 };
219
220 vc_GTP := GTP_Emulation_CT.create(id);
221 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
222}
223
Harald Weltebd194722018-02-16 22:11:08 +0100224private function f_init_vty() runs on test_CT {
225 map(self:SGSNVTY, system:SGSNVTY);
226 f_vty_set_prompts(SGSNVTY);
227 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200228 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100229 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
230}
231
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200232private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
233 if (enable) {
234 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
235 } else {
236 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
237 }
238}
239
Harald Weltebd194722018-02-16 22:11:08 +0100240
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200241/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
242function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100243 if (g_initialized == true) {
244 return;
245 }
246 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100247 g_gb[0].cfg := {
248 nsei := 96,
249 bvci := 196,
250 cell_id := {
251 ra_id := {
252 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100253 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100254 rac := 0
255 },
256 cell_id := 20960
257 },
258 sgsn_role := false
259 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200260 g_gb[1].cfg := {
261 nsei := 97,
262 bvci := 210,
263 cell_id := {
264 ra_id := {
265 lai := {
266 mcc_mnc := mcc_mnc, lac := 13200},
267 rac := 0
268 },
269 cell_id := 20961
270 },
271 sgsn_role := false
272 };
273 g_gb[2].cfg := {
274 nsei := 98,
275 bvci := 220,
276 cell_id := {
277 ra_id := {
278 lai := {
279 mcc_mnc := mcc_mnc, lac := 13300},
280 rac := 0
281 },
282 cell_id := 20962
283 },
284 sgsn_role := false
285 };
Harald Welte96a33b02018-02-04 10:36:22 +0100286
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200287 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200288 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
289 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
290 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte5ac31492018-02-15 20:39:13 +0100291 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100292 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200293 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100294}
Harald Welte96a33b02018-02-04 10:36:22 +0100295
Harald Welte5ac31492018-02-15 20:39:13 +0100296type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
297
298/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200299function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100300 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100301runs on test_CT return BSSGP_ConnHdlr {
302 var BSSGP_ConnHdlr vc_conn;
303 var SGSN_ConnHdlrNetworkPars net_pars := {
304 expect_ptmsi := true,
305 expect_auth := true,
306 expect_ciph := false
307 };
308 var BSSGP_ConnHdlrPars pars := {
309 imei := f_gen_imei(imsi_suffix),
310 imsi := f_gen_imsi(imsi_suffix),
311 msisdn := f_gen_msisdn(imsi_suffix),
312 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100313 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100314 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100315 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100316 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200317 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Harald Welte5ac31492018-02-15 20:39:13 +0100318 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100319 net := net_pars,
320 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100321 };
322
323 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200324 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
325 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
326 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
327 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
328 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
329 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100330
331 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
332 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
333
Harald Welteeded9ad2018-02-17 20:57:34 +0100334 connect(vc_conn:GTP, vc_GTP:CLIENT);
335 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
336
Harald Welte5ac31492018-02-15 20:39:13 +0100337 vc_conn.start(f_handler_init(fn, id, pars));
338 return vc_conn;
339}
340
Harald Welte62e29582018-02-16 21:17:11 +0100341private altstep as_Tguard() runs on BSSGP_ConnHdlr {
342 [] g_Tguard.timeout {
343 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200344 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100345 }
346}
347
Harald Welte5ac31492018-02-15 20:39:13 +0100348/* first function called in every ConnHdlr */
349private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
350runs on BSSGP_ConnHdlr {
351 /* do some common stuff like setting up g_pars */
352 g_pars := pars;
353
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200354 llc := f_llc_create(false);
355
Harald Welte5ac31492018-02-15 20:39:13 +0100356 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200357 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100358 /* tell GSUP dispatcher to send this IMSI to us */
359 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100360 /* tell GTP dispatcher to send this IMSI to us */
361 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100362
Harald Welte62e29582018-02-16 21:17:11 +0100363 g_Tguard.start(pars.t_guard);
364 activate(as_Tguard());
365
Harald Welte5ac31492018-02-15 20:39:13 +0100366 /* call the user-supplied test case function */
367 fn.apply(id);
368 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100369}
370
371/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100372 * Detach without Attach
373 * SM procedures without attach / RAU
374 * ATTACH / RAU
375 ** with / without authentication
376 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100377 * re-transmissions of LLC frames
378 * PDP Context activation
379 ** with different GGSN config in SGSN VTY
380 ** with different PDP context type (v4/v6/v46)
381 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100382 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100383 */
384
385testcase TC_wait_ns_up() runs on test_CT {
386 f_init();
387 f_sleep(20.0);
388}
389
Harald Weltea05b8072019-04-23 22:35:05 +0200390function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
391 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
392 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
393}
394
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200395function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
396 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
397 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
398 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200399 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200400}
401
Harald Welteca362462019-05-02 20:11:21 +0200402altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100403 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welteca362462019-05-02 20:11:21 +0200404 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100405 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteca362462019-05-02 20:11:21 +0200406 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100407 repeat;
408 }
Harald Welteca362462019-05-02 20:11:21 +0200409 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100410 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welteca362462019-05-02 20:11:21 +0200411 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100412 repeat;
413 }
414}
Harald Welte96a33b02018-02-04 10:36:22 +0100415
Harald Welteca362462019-05-02 20:11:21 +0200416/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
417function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
418runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
419 var BssgpDecoded bd;
420 var PDU_L3_SGSN_MS l3_mt;
421 alt {
422 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(rx_tpl)) -> value bd {
423 l3_mt := bd.l3_mt;
424 }
425 }
426 return l3_mt;
427}
428
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200429/* perform GMM authentication (if expected).
430 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
431 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200432function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100433 var PDU_L3_MS_SGSN l3_mo;
434 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200435 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100436 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200437 var GSUP_IE auth_tuple;
438 var template AuthenticationParameterAUTNTLV autn;
439
440 if (umts_aka_challenge) {
441 g_pars.vec := f_gen_auth_vec_3g();
442 autn := {
443 elementIdentifier := '28'O,
444 lengthIndicator := lengthof(g_pars.vec.autn),
445 autnValue := g_pars.vec.autn
446 };
447
448 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
449 g_pars.vec.sres,
450 g_pars.vec.kc,
451 g_pars.vec.ik,
452 g_pars.vec.ck,
453 g_pars.vec.autn,
454 g_pars.vec.res));
455 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
456 } else {
457 g_pars.vec := f_gen_auth_vec_2g();
458 autn := omit;
459 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
460 g_pars.vec.sres,
461 g_pars.vec.kc));
462 log("GSUP sends only 2G auth tuple", auth_tuple);
463 }
Harald Welteca362462019-05-02 20:11:21 +0200464
Harald Welte5ac31492018-02-15 20:39:13 +0100465 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
466 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200467
468 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
469 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200470 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100471 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200472 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
473
474 if (umts_aka_challenge and not force_gsm_sres) {
475 /* set UMTS response instead */
476 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
477 valueField := substr(g_pars.vec.res, 0, 4)
478 };
479 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
480 elementIdentifier := '21'O,
481 lengthIndicator := lengthof(g_pars.vec.res) - 4,
482 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
483 };
484 }
485
486 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100487 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
488 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
489 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
490 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
491 }
Harald Welteca362462019-05-02 20:11:21 +0200492 f_send_l3_gmm_llc(l3_mo, gb_idx);
Harald Welte76dee092018-02-16 22:12:59 +0100493 } else {
494 /* wait for identity procedure */
495 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100496 }
Harald Welte76dee092018-02-16 22:12:59 +0100497
Harald Welte5ac31492018-02-15 20:39:13 +0100498 deactivate(di);
499}
500
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200501function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100502 g_pars.p_tmsi := p_tmsi;
503 /* update TLLI */
504 g_pars.tlli_old := g_pars.tlli;
505 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200506 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100507}
508
Harald Welte04683d02018-02-16 22:43:45 +0100509function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
510 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100511 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200512 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100513 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200514 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200515 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100516 }
Harald Welte04683d02018-02-16 22:43:45 +0100517 g_pars.ra := aa.routingAreaIdentification;
518 if (ispresent(aa.allocatedPTMSI)) {
519 if (not g_pars.net.expect_ptmsi) {
520 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200521 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100522 }
Harald Weltef70997d2018-02-17 10:11:19 +0100523 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100524 }
525 if (ispresent(aa.msIdentity)) {
526 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200527 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100528 }
529 /* P-TMSI.sig */
530 if (ispresent(aa.ptmsiSignature)) {
531 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
532 }
533 /* updateTimer */
534 // aa.readyTimer
535 /* T3302, T3319, T3323, T3312_ext, T3324 */
536}
537
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200538function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100539 /* mandatory IE */
540 g_pars.ra := ra.routingAreaId;
541 if (ispresent(ra.allocatedPTMSI)) {
542 if (not g_pars.net.expect_ptmsi) {
543 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200544 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100545 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200546 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100547 }
548 if (ispresent(ra.msIdentity)) {
549 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200550 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100551 }
552 /* P-TMSI.sig */
553 if (ispresent(ra.ptmsiSignature)) {
554 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
555 }
556 /* updateTimer */
557 // aa.readyTimer
558 /* T3302, T3319, T3323, T3312_ext, T3324 */
559}
560
561
Harald Welte5a4fa042018-02-16 20:59:21 +0100562function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
563 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
564}
565
Harald Welte23178c52018-02-17 09:36:33 +0100566/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100567private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100568 if (ispresent(g_pars.p_tmsi)) {
569 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
570 } else {
571 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
572 }
573}
574
Harald Welte311ec272018-02-17 09:40:03 +0100575private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100576 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100577 /* Expect MSC to perform LU with HLR */
578 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100579 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
580 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
581 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100582 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
583 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
584}
585
Harald Welteca362462019-05-02 20:11:21 +0200586friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100587 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200588 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welteca362462019-05-02 20:11:21 +0200589 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100590
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200591 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
592 * 3G auth vectors */
593 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
594 /* The thing is, if the solSACapability is 'omit', then the
595 * revisionLevelIndicatior is at the wrong place! */
596 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
597
Harald Welteca362462019-05-02 20:11:21 +0200598 f_send_l3_gmm_llc(attach_req, gb_idx);
599 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200600 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100601 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100602
Harald Welteca362462019-05-02 20:11:21 +0200603 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
604 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
605
Harald Welte04683d02018-02-16 22:43:45 +0100606 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welteca362462019-05-02 20:11:21 +0200607 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL, gb_idx);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200608}
609
610private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
611 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100612 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100613}
614
615testcase TC_attach() runs on test_CT {
616 var BSSGP_ConnHdlr vc_conn;
617 f_init();
618 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200619 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100620 vc_conn.done;
621}
622
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100623testcase TC_attach_mnc3() runs on test_CT {
624 var BSSGP_ConnHdlr vc_conn;
625 f_init('023042'H);
626 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200627 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100628 vc_conn.done;
629}
630
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200631private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
632 f_gmm_attach(true, false);
633 setverdict(pass);
634}
635testcase TC_attach_umts_aka_umts_res() runs on test_CT {
636 var BSSGP_ConnHdlr vc_conn;
637 f_init();
638 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200639 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200640 vc_conn.done;
641}
642
643private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
644 f_gmm_attach(true, true);
645 setverdict(pass);
646}
647testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
648 var BSSGP_ConnHdlr vc_conn;
649 f_init();
650 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200651 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200652 vc_conn.done;
653}
654
Harald Welte5b7c8122018-02-16 21:48:17 +0100655/* MS never responds to ID REQ, expect ATTACH REJECT */
656private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100657 var RoutingAreaIdentificationV old_ra := f_random_RAI();
658
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200659 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100660 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200661 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100662 /* don't send ID Response */
663 repeat;
664 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200665 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100666 setverdict(pass);
667 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200668 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100669 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200670 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100671 }
672 }
673}
674testcase TC_attach_auth_id_timeout() runs on test_CT {
675 var BSSGP_ConnHdlr vc_conn;
676 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200677 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb, 2, 40.0);
Harald Welte5b7c8122018-02-16 21:48:17 +0100678 vc_conn.done;
679}
680
681/* HLR never responds to SAI REQ, expect ATTACH REJECT */
682private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100683 var RoutingAreaIdentificationV old_ra := f_random_RAI();
684
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200685 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100686 alt {
687 [] as_mm_identity();
688 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
689 }
690 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200691 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100692 setverdict(pass);
693}
694testcase TC_attach_auth_sai_timeout() runs on test_CT {
695 var BSSGP_ConnHdlr vc_conn;
696 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200697 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100698 vc_conn.done;
699}
700
Harald Weltefe253882018-02-17 09:25:00 +0100701/* HLR rejects SAI, expect ATTACH REJECT */
702private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100703 var RoutingAreaIdentificationV old_ra := f_random_RAI();
704
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200705 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100706 alt {
707 [] as_mm_identity();
708 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
709 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
710 }
711 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200712 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100713 setverdict(pass);
714}
715testcase TC_attach_auth_sai_reject() runs on test_CT {
716 var BSSGP_ConnHdlr vc_conn;
717 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200718 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100719 vc_conn.done;
720}
721
Harald Welte5b7c8122018-02-16 21:48:17 +0100722/* HLR never responds to UL REQ, expect ATTACH REJECT */
723private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100724 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100725 var RoutingAreaIdentificationV old_ra := f_random_RAI();
726
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200727 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100728 f_gmm_auth();
729 /* Expect MSC to perform LU with HLR */
730 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
731 /* Never follow-up with ISD_REQ or UL_RES */
732 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200733 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100734 setverdict(pass);
735 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200736 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100737 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100738 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200739 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100740 }
741 }
742}
743testcase TC_attach_gsup_lu_timeout() runs on test_CT {
744 var BSSGP_ConnHdlr vc_conn;
745 f_init();
746 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200747 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100748 vc_conn.done;
749}
750
Harald Welteb7c14e92018-02-17 09:29:16 +0100751/* HLR rejects UL REQ, expect ATTACH REJECT */
752private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
753 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100754 var RoutingAreaIdentificationV old_ra := f_random_RAI();
755
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200756 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100757 f_gmm_auth();
758 /* Expect MSC to perform LU with HLR */
759 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
760 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
761 }
762 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200763 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100764 setverdict(pass);
765 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200766 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100767 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
768 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200769 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100770 }
771 }
772}
773testcase TC_attach_gsup_lu_reject() runs on test_CT {
774 var BSSGP_ConnHdlr vc_conn;
775 f_init();
776 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200777 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100778 vc_conn.done;
779}
780
781
Harald Welte3823e2e2018-02-16 21:53:48 +0100782/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
783private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100784 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100785 var RoutingAreaIdentificationV old_ra := f_random_RAI();
786
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200787 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100788 f_gmm_auth();
789 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100790 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100791
Alexander Couzens0e510e62018-07-28 23:06:00 +0200792 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100793 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
794 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200795 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100796 setverdict(pass);
797}
Harald Welte3823e2e2018-02-16 21:53:48 +0100798testcase TC_attach_combined() runs on test_CT {
799 var BSSGP_ConnHdlr vc_conn;
800 f_init();
801 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200802 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100803 vc_conn.done;
804}
805
Harald Welte76dee092018-02-16 22:12:59 +0100806/* Attempt of GPRS ATTACH in 'accept all' mode */
807private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100808 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100809 var RoutingAreaIdentificationV old_ra := f_random_RAI();
810
811 g_pars.net.expect_auth := false;
812
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200813 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100814 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200815 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100816 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
817 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200818 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100819 setverdict(pass);
820}
821testcase TC_attach_accept_all() runs on test_CT {
822 var BSSGP_ConnHdlr vc_conn;
823 f_init();
824 f_sleep(1.0);
825 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200826 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100827 vc_conn.done;
828}
Harald Welte5b7c8122018-02-16 21:48:17 +0100829
Harald Welteb2124b22018-02-16 22:26:56 +0100830/* Attempt of GPRS ATTACH in 'accept all' mode */
831private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100832 var RoutingAreaIdentificationV old_ra := f_random_RAI();
833
834 /* Simulate a foreign IMSI */
835 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200836 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100837
838 g_pars.net.expect_auth := false;
839
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200840 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100841 alt {
842 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200843 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100844 setverdict(pass);
845 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200846 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100847 setverdict(pass);
848 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200849 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200850 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200851 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200852 }
Harald Welteb2124b22018-02-16 22:26:56 +0100853 }
854}
855testcase TC_attach_closed() runs on test_CT {
856 var BSSGP_ConnHdlr vc_conn;
857 f_init();
858 f_sleep(1.0);
859 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
860 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200861 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100862 vc_conn.done;
863 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200864 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100865 vc_conn.done;
866}
867
Harald Welte04683d02018-02-16 22:43:45 +0100868/* Routing Area Update from Unknown TLLI -> REJECT */
869private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100870 var RoutingAreaIdentificationV old_ra := f_random_RAI();
871
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200872 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +0100873 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200874 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100875 setverdict(pass);
876 }
877 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200878 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100879 }
880}
881testcase TC_rau_unknown() runs on test_CT {
882 var BSSGP_ConnHdlr vc_conn;
883 f_init();
884 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200885 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100886 vc_conn.done;
887}
888
Harald Welte91636de2018-02-17 10:16:14 +0100889private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
890 var BssgpDecoded bd;
891
892 /* first perform regular attach */
893 f_TC_attach(id);
894
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200895 f_routing_area_update(g_pars.ra);
896
Harald Welte91636de2018-02-17 10:16:14 +0100897}
898testcase TC_attach_rau() runs on test_CT {
899 var BSSGP_ConnHdlr vc_conn;
900 f_init();
901 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200902 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100903 vc_conn.done;
904}
Harald Welte04683d02018-02-16 22:43:45 +0100905
Harald Welte6abb9fe2018-02-17 15:24:48 +0100906/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200907function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100908 var BssgpDecoded bd;
909 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200910 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100911 if (expect_purge) {
912 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
913 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
914 }
915 T.start;
916 alt {
917 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
918 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200919 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100920 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200921 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100922 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +0200923 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200924 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100925 /* TODO: check if any PDP contexts are deactivated on network side? */
926 }
Alexander Couzens44aa0772019-05-11 01:21:03 +0200927 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(?)) -> value bd {
928 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
929 mtc.stop;
930 }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100931 [power_off] T.timeout {
932 setverdict(pass);
933 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200934 [not power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100935 g_pars.ra := omit;
936 setverdict(pass);
937 /* TODO: check if any PDP contexts are deactivated on network side? */
938 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200939 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100940 }
941}
942
943/* IMSI DETACH (non-power-off) for unknown TLLI */
944private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
945 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
946}
947testcase TC_detach_unknown_nopoweroff() runs on test_CT {
948 var BSSGP_ConnHdlr vc_conn;
949 f_init();
950 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200951 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100952 vc_conn.done;
953}
954
955/* IMSI DETACH (power-off) for unknown TLLI */
956private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
957 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
958}
959testcase TC_detach_unknown_poweroff() runs on test_CT {
960 var BSSGP_ConnHdlr vc_conn;
961 f_init();
962 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200963 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100964 vc_conn.done;
965}
966
967/* IMSI DETACH (non-power-off) for known TLLI */
968private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
969 /* first perform regular attach */
970 f_TC_attach(id);
971
972 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
973}
974testcase TC_detach_nopoweroff() runs on test_CT {
975 var BSSGP_ConnHdlr vc_conn;
976 f_init();
977 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200978 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100979 vc_conn.done;
980}
981
982/* IMSI DETACH (power-off) for known TLLI */
983private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
984 /* first perform regular attach */
985 f_TC_attach(id);
986
987 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
988}
989testcase TC_detach_poweroff() runs on test_CT {
990 var BSSGP_ConnHdlr vc_conn;
991 f_init();
992 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200993 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100994 vc_conn.done;
995}
996
Harald Welteeded9ad2018-02-17 20:57:34 +0100997type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100998 BIT3 tid, /* L3 Transaction ID */
999 BIT4 nsapi, /* SNDCP NSAPI */
1000 BIT4 sapi, /* LLC SAPI */
1001 QoSV qos, /* QoS parameters */
1002 PDPAddressV addr, /* IP address */
1003 octetstring apn optional, /* APN name */
1004 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1005 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001006 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001007 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001008
Harald Welte822f9102018-02-18 20:39:06 +01001009 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1010 OCT4 ggsn_tei_u, /* GGSN TEI User */
1011 octetstring ggsn_ip_c, /* GGSN IP Control */
1012 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001013 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001014
Harald Welte822f9102018-02-18 20:39:06 +01001015 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1016 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1017 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1018 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001019};
1020
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001021
1022private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1023 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1024 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1025 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1026 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1027 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1028 f_gtp_register_teid(apars.ggsn_tei_c);
1029 f_gtp_register_teid(apars.ggsn_tei_u);
1030}
1031
Harald Weltef7191672019-05-02 20:37:23 +02001032function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1033runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001034 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1035 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001036 var template Recovery_gtpc recovery := omit;
1037
1038 if (send_recovery) {
1039 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1040 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001041
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001042 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001043 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001044 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1045 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1046 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1047 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1048 apars.sgsn_tei_c, apars.gtp_resp_cause,
1049 apars.ggsn_tei_c, apars.ggsn_tei_u,
1050 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001051 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1052 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001053 }
1054 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001055 [exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001056 setverdict(pass);
1057 }
Harald Weltef7191672019-05-02 20:37:23 +02001058 [exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001059 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001060 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001061 }
Harald Weltef7191672019-05-02 20:37:23 +02001062 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001063 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001064 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001065 }
Harald Weltef7191672019-05-02 20:37:23 +02001066 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
1067 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1068 mtc.stop;
1069 }
1070 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001071 setverdict(pass);
1072 }
Harald Weltef7191672019-05-02 20:37:23 +02001073 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001074 }
1075}
1076
Harald Weltef7191672019-05-02 20:37:23 +02001077function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1078runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001079 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1080 var Gtp1cUnitdata g_ud;
1081
Harald Weltef7191672019-05-02 20:37:23 +02001082 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001083 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1084 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001085 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001086 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1087 }
1088 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001089 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001090 setverdict(pass);
1091 }
Harald Weltef7191672019-05-02 20:37:23 +02001092 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001093 }
1094}
1095
Harald Weltef7191672019-05-02 20:37:23 +02001096function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1097runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001098 var Gtp1cUnitdata g_ud;
1099 var integer seq_nr := 23;
1100 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1101
Harald Weltef7191672019-05-02 20:37:23 +02001102 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001103 if (error_ind) {
1104 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1105 } else {
1106 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1107 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001108
1109 timer T := 5.0;
1110 T.start;
1111
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001112 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001113 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
1114 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001115 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001116 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1117 repeat;
1118 }
1119 [] T.timeout {
1120 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1121 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001122 }
1123}
1124
Harald Welte6f203162018-02-18 22:04:55 +01001125
Harald Welteeded9ad2018-02-17 20:57:34 +01001126/* Table 10.5.156/3GPP TS 24.008 */
1127template (value) QoSV t_QosDefault := {
1128 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1129 delayClass := '100'B, /* best effort */
1130 spare1 := '00'B,
1131 precedenceClass := '010'B, /* normal */
1132 spare2 := '0'B,
1133 peakThroughput := '0000'B, /* subscribed */
1134 meanThroughput := '00000'B, /* subscribed */
1135 spare3 := '000'B,
1136 deliverErroneusSDU := omit,
1137 deliveryOrder := omit,
1138 trafficClass := omit,
1139 maxSDUSize := omit,
1140 maxBitrateUplink := omit,
1141 maxBitrateDownlink := omit,
1142 sduErrorRatio := omit,
1143 residualBER := omit,
1144 trafficHandlingPriority := omit,
1145 transferDelay := omit,
1146 guaranteedBitRateUplink := omit,
1147 guaranteedBitRateDownlink := omit,
1148 sourceStatisticsDescriptor := omit,
1149 signallingIndication := omit,
1150 spare4 := omit,
1151 maxBitrateDownlinkExt := omit,
1152 guaranteedBitRateDownlinkExt := omit,
1153 maxBitrateUplinkExt := omit,
1154 guaranteedBitRateUplinkExt := omit,
1155 maxBitrateDownlinkExt2 := omit,
1156 guaranteedBitRateDownlinkExt2 := omit,
1157 maxBitrateUplinkExt2 := omit,
1158 guaranteedBitRateUplinkExt2 := omit
1159}
1160
1161/* 10.5.6.4 / 3GPP TS 24.008 */
1162template (value) PDPAddressV t_AddrIPv4dyn := {
1163 pdpTypeOrg := '0001'B, /* IETF */
1164 spare := '0000'B,
1165 pdpTypeNum := '21'O, /* IPv4 */
1166 addressInfo := omit
1167}
1168template (value) PDPAddressV t_AddrIPv6dyn := {
1169 pdpTypeOrg := '0001'B, /* IETF */
1170 spare := '0000'B,
1171 pdpTypeNum := '53'O, /* IPv6 */
1172 addressInfo := omit
1173}
1174
Harald Welte37692d82018-02-18 15:21:34 +01001175template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001176 tid := '000'B,
1177 nsapi := '0101'B, /* < 5 are reserved */
1178 sapi := '0011'B, /* 3/5/9/11 */
1179 qos := t_QosDefault,
1180 addr := t_AddrIPv4dyn,
1181 apn := omit,
1182 pco := omit,
1183 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001184 gtp_resp_cause := int2oct(128, 1),
1185 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001186
1187 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001188 ggsn_tei_c := f_rnd_octstring(4),
1189 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001190 ggsn_ip_c := f_inet_addr(ggsn_ip),
1191 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001192 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001193
Harald Welteeded9ad2018-02-17 20:57:34 +01001194 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001195 sgsn_tei_u := omit,
1196 sgsn_ip_c := omit,
1197 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001198}
1199
Harald Welte37692d82018-02-18 15:21:34 +01001200template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1201 connId := 1,
1202 remName := f_inet_ntoa(ip),
1203 remPort := GTP1U_PORT
1204}
1205
1206template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1207 connId := 1,
1208 remName := f_inet_ntoa(ip),
1209 remPort := GTP1C_PORT
1210}
1211
1212private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1213 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1214 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1215}
1216
Harald Weltef7191672019-05-02 20:37:23 +02001217private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
1218 [] BSSGP[gb_idx].receive(tr_BD_LLC(tr_LLC_XID_MT_CMD(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001219 repeat;
1220 }
1221}
1222
1223template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1224 pDU_SN_UNITDATA := {
1225 nsapi := nsapi,
1226 moreBit := ?,
1227 snPduType := '1'B,
1228 firstSegmentIndicator := ?,
1229 spareBit := ?,
1230 pcomp := ?,
1231 dcomp := ?,
1232 npduNumber := ?,
1233 segmentNumber := ?,
1234 npduNumberContinued := ?,
1235 dataSegmentSnUnitdataPdu := payload
1236 }
1237}
1238
1239/* simple case: single segment, no compression */
1240template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1241 pDU_SN_UNITDATA := {
1242 nsapi := nsapi,
1243 moreBit := '0'B,
1244 snPduType := '1'B,
1245 firstSegmentIndicator := '1'B,
1246 spareBit := '0'B,
1247 pcomp := '0000'B,
1248 dcomp := '0000'B,
1249 npduNumber := '0000'B,
1250 segmentNumber := '0000'B,
1251 npduNumberContinued := '00'O,
1252 dataSegmentSnUnitdataPdu := payload
1253 }
1254}
1255
1256/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001257private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1258runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001259 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1260 f_gtpu_send(apars, payload);
1261 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1262 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001263 [] as_xid(apars, gb_idx);
1264 [] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001265 }
1266}
1267
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001268/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001269private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1270runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001271 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1272 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1273 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001274 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001275 /* Expect PDU via GTP from SGSN on simulated GGSN */
1276 alt {
1277 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1278 }
1279}
1280
Harald Welteeded9ad2018-02-17 20:57:34 +01001281private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001282 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001283
1284 /* first perform regular attach */
1285 f_TC_attach(id);
1286
1287 f_pdp_ctx_act(apars);
1288}
1289testcase TC_attach_pdp_act() runs on test_CT {
1290 var BSSGP_ConnHdlr vc_conn;
1291 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001292 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001293 vc_conn.done;
1294}
Harald Welteb2124b22018-02-16 22:26:56 +01001295
Harald Welte835b15f2018-02-18 14:39:11 +01001296/* PDP Context activation for not-attached subscriber; expect fail */
1297private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001298 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001299 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001300 apars.apn, apars.pco));
1301 alt {
1302 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001303 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001304 setverdict(pass);
1305 }
1306 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1307 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001308 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001309 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001310 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001311 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001312 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001313 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001314 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001315 }
1316}
1317testcase TC_pdp_act_unattached() runs on test_CT {
1318 var BSSGP_ConnHdlr vc_conn;
1319 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001320 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001321 vc_conn.done;
1322}
1323
Harald Welte37692d82018-02-18 15:21:34 +01001324/* ATTACH + PDP CTX ACT + user plane traffic */
1325private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1326 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1327
1328 /* first perform regular attach */
1329 f_TC_attach(id);
1330 /* then activate PDP context */
1331 f_pdp_ctx_act(apars);
1332 /* then transceive a downlink PDU */
1333 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1334 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1335}
1336testcase TC_attach_pdp_act_user() runs on test_CT {
1337 var BSSGP_ConnHdlr vc_conn;
1338 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001339 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001340 vc_conn.done;
1341}
1342
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001343/* ATTACH + PDP CTX ACT; reject from GGSN */
1344private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1345 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1346
1347 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1348 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1349
1350 /* first perform regular attach */
1351 f_TC_attach(id);
1352 /* then activate PDP context */
1353 f_pdp_ctx_act(apars);
1354}
1355testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1356 var BSSGP_ConnHdlr vc_conn;
1357 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001358 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001359 vc_conn.done;
1360}
Harald Welte835b15f2018-02-18 14:39:11 +01001361
Harald Welte6f203162018-02-18 22:04:55 +01001362/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1363private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1364 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1365
1366 /* first perform regular attach */
1367 f_TC_attach(id);
1368 /* then activate PDP context */
1369 f_pdp_ctx_act(apars);
1370 /* then transceive a downlink PDU */
1371 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1372 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1373
1374 f_pdp_ctx_deact_mo(apars, '00'O);
1375}
1376testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1377 var BSSGP_ConnHdlr vc_conn;
1378 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001379 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb, 21);
Harald Welte6f203162018-02-18 22:04:55 +01001380 vc_conn.done;
1381}
1382
Harald Welte57b9b7f2018-02-18 22:28:13 +01001383/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1384private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1385 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1386
1387 /* first perform regular attach */
1388 f_TC_attach(id);
1389 /* then activate PDP context */
1390 f_pdp_ctx_act(apars);
1391 /* then transceive a downlink PDU */
1392 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1393 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1394
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001395 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001396}
1397testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1398 var BSSGP_ConnHdlr vc_conn;
1399 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001400 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb, 22);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001401 vc_conn.done;
1402}
1403
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001404/* ATTACH + ATTACH (2nd) */
1405private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1406 g_pars.t_guard := 5.0;
1407
1408 /* first perform regular attach */
1409 f_TC_attach(id);
1410
1411 /* second to perform regular attach */
1412 f_TC_attach(id);
1413}
1414
1415
1416testcase TC_attach_second_attempt() runs on test_CT {
1417 var BSSGP_ConnHdlr vc_conn;
1418 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001419 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001420 vc_conn.done;
1421}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001422
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001423private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001424 var Gtp1cUnitdata g_ud;
1425 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1426
1427 /* first perform regular attach */
1428 f_TC_attach(id);
1429 /* Activate a pdp context against the GGSN */
1430 f_pdp_ctx_act(apars);
1431 /* Wait to receive first echo request and send initial Restart counter */
1432 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1433 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1434 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1435 }
1436 /* Wait to receive second echo request and send incremented Restart
1437 counter. This will fake a restarted GGSN, and pdp ctx allocated
1438 should be released by SGSN */
1439 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1440 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1441 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1442 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1443 }
1444 var OCT1 cause_network_failure := int2oct(38, 1)
1445 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001446 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001447 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001448 setverdict(pass);
1449 }
1450 [] as_xid(apars);
1451 }
1452 setverdict(pass);
1453}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001454/* ATTACH + trigger Recovery procedure through EchoResp */
1455testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001456 var BSSGP_ConnHdlr vc_conn;
1457 g_use_echo := true
1458 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001459 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_echo), testcasename(), g_gb, 23, 30.0);
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001460 vc_conn.done;
1461 g_use_echo := false
1462}
1463
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001464private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1465 var Gtp1cUnitdata g_ud;
1466 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1467 var integer seq_nr := 23;
1468 var GtpPeer peer;
1469 /* first perform regular attach */
1470 f_TC_attach(id);
1471
1472 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1473 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1474 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1475 f_pdp_ctx_act(apars, true);
1476
1477 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1478/* received. */
1479 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1480
1481 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1482 would be great to have an active pdp context here before triggering
1483 Recovery, and making sure the the DEACT request is sent by the SGSN.
1484 */
1485
1486 /* Activate a pdp context against the GGSN, send incremented Recovery
1487 IE. This should trigger the recovery path, but still this specific
1488 CTX activation should work. */
1489 apars.exp_rej_cause := omit; /* default value for tests */
1490 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1491 f_pdp_ctx_act(apars, true);
1492
1493 setverdict(pass);
1494}
1495/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1496testcase TC_attach_restart_ctr_create() runs on test_CT {
1497 var BSSGP_ConnHdlr vc_conn;
1498 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001499 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb, 24, 30.0);
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001500 vc_conn.done;
1501}
1502
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001503/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1504private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1505 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1506 var integer seq_nr := 23;
1507 var GtpPeer peer;
1508 var integer i;
1509
1510 /* first perform regular attach */
1511 f_TC_attach(id);
1512 /* then activate PDP context */
1513 f_pdp_ctx_act(apars);
1514
Alexander Couzens0e510e62018-07-28 23:06:00 +02001515 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001516 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1517 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1518
1519 for (i := 0; i < 5; i := i+1) {
1520 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001521 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001522 [] as_xid(apars);
1523 }
1524 }
1525
1526 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1527
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001528 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001529 setverdict(pass);
1530}
1531testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1532 var BSSGP_ConnHdlr vc_conn;
1533 f_init();
1534 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001535 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb, 25, 60.0);
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001536 vc_conn.done;
1537}
1538
Alexander Couzens5e307b42018-05-22 18:12:20 +02001539private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1540 /* MS: perform regular attach */
1541 f_TC_attach(id);
1542
1543 /* HLR: cancel the location request */
1544 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1545 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001546
1547 /* ensure no Detach Request got received */
1548 timer T := 5.0;
1549 T.start;
1550 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001551 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001552 T.stop;
1553 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001554 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001555 }
1556 [] T.timeout {
1557 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001558 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001559 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001560 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001561 repeat;
1562 }
1563 }
1564}
1565
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001566/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1567private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1568 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1569
1570 /* first perform regular attach */
1571 f_TC_attach(id);
1572 /* then activate PDP context */
1573 f_pdp_ctx_act(apars);
1574 /* then transceive a downlink PDU */
1575 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1576
1577 /* Send Error indication as response from upload PDU and expect deact towards MS */
1578 f_pdp_ctx_deact_mt(apars, true);
1579}
1580testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1581 var BSSGP_ConnHdlr vc_conn;
1582 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001583 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 +02001584 vc_conn.done;
1585}
1586
Alexander Couzens5e307b42018-05-22 18:12:20 +02001587testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1588 /* MS <-> SGSN: GMM Attach
1589 * HLR -> SGSN: Cancel Location Request
1590 * HLR <- SGSN: Cancel Location Ack
1591 */
1592 var BSSGP_ConnHdlr vc_conn;
1593 f_init();
1594 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001595 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001596 vc_conn.done;
1597}
1598
1599
Alexander Couzensc87967a2018-05-22 16:09:54 +02001600private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1601 /* MS: perform regular attach */
1602 f_TC_attach(id);
1603
1604 /* HLR: cancel the location request */
1605 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1606 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1607 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1608
1609 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001610 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001611 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001612
1613 setverdict(pass);
1614}
1615
1616testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1617 /* MS <-> SGSN: GMM Attach
1618 * HLR -> SGSN: Cancel Location Request
1619 * HLR <- SGSN: Cancel Location Ack
1620 * MS <- SGSN: Detach Request
1621 * SGSN-> MS: Detach Complete
1622 */
1623 var BSSGP_ConnHdlr vc_conn;
1624 f_init();
1625 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001626 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001627 vc_conn.done;
1628}
1629
1630
Alexander Couzens6c47f292018-05-22 17:09:49 +02001631private function f_hlr_location_cancel_request_unknown_subscriber(
1632 charstring id,
1633 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1634
1635 /* HLR: cancel the location request */
1636 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1637
1638 /* cause 2 = IMSI_UNKNOWN */
1639 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1640
1641 setverdict(pass);
1642}
1643
1644private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001645 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001646}
1647
1648testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1649 /* HLR -> SGSN: Cancel Location Request
1650 * HLR <- SGSN: Cancel Location Error
1651 */
1652
1653 var BSSGP_ConnHdlr vc_conn;
1654 f_init();
1655 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001656 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 +02001657 vc_conn.done;
1658}
1659
1660private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001661 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001662}
1663
1664testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1665 /* HLR -> SGSN: Cancel Location Request
1666 * HLR <- SGSN: Cancel Location Error
1667 */
1668
1669 var BSSGP_ConnHdlr vc_conn;
1670 f_init();
1671 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001672 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 +02001673 vc_conn.done;
1674}
1675
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001676private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1677 f_TC_attach(id);
1678 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1679}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001680
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001681testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1682 /* MS <-> SGSN: Attach
1683 * MS -> SGSN: Detach Req (Power off)
1684 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1685 */
1686 var BSSGP_ConnHdlr vc_conn;
1687 var integer id := 33;
1688 var charstring imsi := hex2str(f_gen_imsi(id));
1689
1690 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001691 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001692 vc_conn.done;
1693
1694 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1695}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001696
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001697/* Attempt an attach, but loose the Identification Request (IMEI) */
1698private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1699 var integer count_req := 0;
1700 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1701
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001702 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 +02001703
1704 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001705 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001706 /* break */
1707 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001708 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001709 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001710 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001711 repeat;
1712 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001713 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001714 /* ignore ID REQ IMEI */
1715 count_req := count_req + 1;
1716 repeat;
1717 }
1718 }
1719 if (count_req != 5) {
1720 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001721 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001722 }
1723 setverdict(pass);
1724}
1725
1726testcase TC_attach_no_imei_response() runs on test_CT {
1727 /* MS -> SGSN: Attach Request IMSI
1728 * MS <- SGSN: Identity Request IMSI (optional)
1729 * MS -> SGSN: Identity Response IMSI (optional)
1730 * MS <- SGSN: Identity Request IMEI
1731 * MS -x SGSN: no response
1732 * MS <- SGSN: re-send: Identity Request IMEI 4x
1733 * MS <- SGSN: Attach Reject
1734 */
1735 var BSSGP_ConnHdlr vc_conn;
1736 f_init();
1737 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001738 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 +02001739 vc_conn.done;
1740}
1741
Alexander Couzens53f20562018-06-12 16:24:12 +02001742/* Attempt an attach, but loose the Identification Request (IMSI) */
1743private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1744 var integer count_req := 0;
1745 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1746
1747 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1748 g_pars.p_tmsi := 'c0000035'O;
1749
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001750 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 +02001751
1752 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001753 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001754 /* break */
1755 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001756 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001757 /* ignore ID REQ IMSI */
1758 count_req := count_req + 1;
1759 repeat;
1760 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001761 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001762 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001763 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001764 repeat;
1765 }
1766 }
1767 if (count_req != 5) {
1768 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001769 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001770 }
1771 setverdict(pass);
1772}
1773
1774testcase TC_attach_no_imsi_response() runs on test_CT {
1775 /* MS -> SGSN: Attach Request TMSI (unknown)
1776 * MS <- SGSN: Identity Request IMEI (optional)
1777 * MS -> SGSN: Identity Response IMEI (optional)
1778 * MS <- SGSN: Identity Request IMSI
1779 * MS -x SGSN: no response
1780 * MS <- SGSN: re-send: Identity Request IMSI 4x
1781 * MS <- SGSN: Attach Reject
1782 */
1783 var BSSGP_ConnHdlr vc_conn;
1784 f_init();
1785 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001786 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 +02001787 vc_conn.done;
1788}
1789
Alexander Couzenscf818962018-06-05 18:00:00 +02001790private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1791 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1792}
1793
1794testcase TC_attach_check_subscriber_list() runs on test_CT {
1795 /* MS <-> SGSN: Attach
1796 * VTY -> SGSN: Check if MS is in subscriber cache
1797 */
1798 var BSSGP_ConnHdlr vc_conn;
1799 var integer id := 34;
1800 var charstring imsi := hex2str(f_gen_imsi(id));
1801
1802 f_init();
1803 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001804 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001805 vc_conn.done;
1806
1807 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1808 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1809}
1810
Alexander Couzensf9858652018-06-07 16:14:53 +02001811private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1812 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1813 var BssgpDecoded bd;
1814
1815 /* unregister the old IMSI */
1816 f_bssgp_client_unregister(g_pars.imsi);
1817 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001818 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001819 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001820
1821 /* there is no auth */
1822 g_pars.net.expect_auth := false;
1823
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001824 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 +02001825 f_gmm_auth();
1826 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001827 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001828 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001829 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001830 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001831 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001832 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001833 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001834 setverdict(pass);
1835 }
1836 }
1837}
Alexander Couzens03d12242018-08-07 16:13:52 +02001838
1839private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1840
1841 f_TC_attach_closed_foreign(id);
1842 f_TC_attach_closed_imsi_added(id);
1843
1844}
1845
1846
Alexander Couzensf9858652018-06-07 16:14:53 +02001847testcase TC_attach_closed_add_vty() runs on test_CT {
1848 /* VTY-> SGSN: policy close
1849 * MS -> SGSN: Attach Request
1850 * MS <- SGSN: Identity Request IMSI
1851 * MS -> SGSN: Identity Response IMSI
1852 * MS <- SGSN: Attach Reject
1853 * VTY-> SGSN: policy imsi-acl add IMSI
1854 * MS -> SGSN: Attach Request
1855 * MS <- SGSN: Identity Request IMSI
1856 * MS -> SGSN: Identity Response IMSI
1857 * MS <- SGSN: Identity Request IMEI
1858 * MS -> SGSN: Identity Response IMEI
1859 * MS <- SGSN: Attach Accept
1860 */
1861 var BSSGP_ConnHdlr vc_conn;
1862 f_init();
1863 f_sleep(1.0);
1864 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1865 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001866 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1867 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001868 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001869 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001870 vc_conn.done;
1871}
1872
Alexander Couzens0085bd72018-06-12 19:08:44 +02001873/* Attempt an attach, but never answer a Attach Complete */
1874private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1875 var integer count_req := 0;
1876
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001877 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 +02001878 f_gmm_auth();
1879
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001880 timer T := 10.0;
1881 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001882 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001883 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001884 /* break */
1885 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001886 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001887 /* ignore */
1888 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001889 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001890 repeat;
1891 }
1892 }
1893 if (count_req != 5) {
1894 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001895 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001896 }
1897 setverdict(pass);
1898}
1899
1900testcase TC_attach_check_complete_resend() runs on test_CT {
1901 /* MS -> SGSN: Attach Request IMSI
1902 * MS <- SGSN: Identity Request *
1903 * MS -> SGSN: Identity Response *
1904 * MS <- SGSN: Attach Complete 5x
1905 */
1906 var BSSGP_ConnHdlr vc_conn;
1907 f_init();
1908 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001909 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 +02001910 vc_conn.done;
1911}
1912
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001913private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
1914 var BssgpDecoded bd;
1915
1916 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001917 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 +02001918 alt {
1919 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001920 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001921 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001922 setverdict(pass);
1923 }
1924 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
1925 setverdict(fail, "Unexpected RAU Reject");
1926 mtc.stop;
1927 }
1928 [] BSSGP[bssgp].receive { repeat; }
1929 }
1930}
1931
Alexander Couzensbfda9212018-07-31 03:17:33 +02001932private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
1933 var BssgpDecoded bd;
1934
1935 /* first perform regular attach */
1936 f_TC_attach(id);
1937
1938 /* then send RAU */
1939 f_routing_area_update(g_pars.ra);
1940
1941 /* do another RAU */
1942 f_routing_area_update(g_pars.ra);
1943
1944 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1945}
1946
1947testcase TC_attach_rau_a_a() runs on test_CT {
1948 /* MS <-> SGSN: Successful Attach
1949 * MS -> SGSN: Routing Area Update Request
1950 * MS <- SGSN: Routing Area Update Accept
1951 * MS -> SGSN: Routing Area Update Request
1952 * MS <- SGSN: Routing Area Update Accept
1953 * MS -> SGSN: Detach (PowerOff)
1954 */
1955 var BSSGP_ConnHdlr vc_conn;
1956 f_init();
1957 f_sleep(1.0);
1958 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
1959 vc_conn.done;
1960}
1961
Alexander Couzensbe837bd2018-07-31 04:20:11 +02001962private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
1963 var BssgpDecoded bd;
1964
1965 f_TC_attach(id);
1966
1967 log("attach complete sending rau");
1968 f_routing_area_update(g_pars.ra, 0);
1969
1970 log("rau complete unregistering");
1971 f_bssgp_client_unregister(g_pars.imsi);
1972 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
1973
1974 log("sending second RAU via different RA");
1975 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
1976
1977 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
1978}
1979
1980testcase TC_attach_rau_a_b() runs on test_CT {
1981 /* MS <-> SGSN: Successful Attach
1982 * MS -> SGSN: Routing Area _a_ Update Request
1983 * MS <- SGSN: Routing Area _a_ Update Accept
1984 * MS -> SGSN: Routing Area _b_ Update Request
1985 * MS <- SGSN: Routing Area _b_ Update Accept
1986 * MS -> SGSN: Detach (PowerOff)
1987 */
1988 var BSSGP_ConnHdlr vc_conn;
1989 f_init();
1990 f_sleep(1.0);
1991 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
1992 vc_conn.done;
1993}
1994
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02001995private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
1996 var integer count_req := 0;
1997 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1998 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
1999 var BssgpDecoded bd;
2000
2001 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2002
2003 alt {
2004 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2005 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2006 mtc.stop;
2007 }
2008 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2009 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2010 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2011 repeat;
2012 }
2013 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2014 /* send out a second GMM_Attach Request.
2015 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2016 * of the same content */
2017 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2018 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
2019 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2020 }
2021 }
2022 f_sleep(1.0);
2023
2024 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2025 alt {
2026 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2027 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2028 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2029 repeat;
2030 }
2031 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2032 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2033 mtc.stop;
2034 }
2035 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2036 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2037 mtc.stop;
2038 }
2039 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2040 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2041 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2042 setverdict(pass);
2043 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2044 }
2045 }
2046}
2047
2048testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2049 /* Testing if the SGSN ignore Attach Request with the exact same content */
2050 /* MS -> SGSN: Attach Request IMSI
2051 * MS <- SGSN: Identity Request IMSI (optional)
2052 * MS -> SGSN: Identity Response IMSI (optional)
2053 * MS <- SGSN: Identity Request IMEI
2054 * MS -> SGSN: Attach Request (2nd)
2055 * MS <- SGSN: Identity Response IMEI
2056 * MS <- SGSN: Attach Accept
2057 * MS -> SGSN: Attach Complete
2058 */
2059 var BSSGP_ConnHdlr vc_conn;
2060 f_init();
2061 f_sleep(1.0);
2062 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2063 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2064 vc_conn.done;
2065}
2066
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002067private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
2068 var BssgpDecoded bd;
2069 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2070
2071 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2072
2073 /* send Attach Request */
2074 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2075 * 3G auth vectors */
2076 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2077 /* The thing is, if the solSACapability is 'omit', then the
2078 * revisionLevelIndicatior is at the wrong place! */
2079 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2080 f_send_l3_gmm_llc(attach_req);
2081
2082 /* do the auth */
2083 var PDU_L3_MS_SGSN l3_mo;
2084 var PDU_L3_SGSN_MS l3_mt;
2085 var default di := activate(as_mm_identity());
2086
2087 var GSUP_IE auth_tuple;
2088 var template AuthenticationParameterAUTNTLV autn;
2089
2090 g_pars.vec := f_gen_auth_vec_3g();
2091 autn := {
2092 elementIdentifier := '28'O,
2093 lengthIndicator := lengthof(g_pars.vec.autn),
2094 autnValue := g_pars.vec.autn
2095 };
2096 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2097 g_pars.vec.sres,
2098 g_pars.vec.kc,
2099 g_pars.vec.ik,
2100 g_pars.vec.ck,
2101 g_pars.vec.autn,
2102 g_pars.vec.res));
2103 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2104 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2105 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2106
2107 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2108 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2109 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2110
2111 /* send the gmm auth failure with resync IE */
2112 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2113
2114 /* wait for the GSUP resync request */
2115 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2116 g_pars.imsi,
2117 g_pars.vec.auts,
2118 g_pars.vec.rand));
2119
2120 /* generate new key material */
2121 g_pars.vec := f_gen_auth_vec_3g();
2122 autn := {
2123 elementIdentifier := '28'O,
2124 lengthIndicator := lengthof(g_pars.vec.autn),
2125 autnValue := g_pars.vec.autn
2126 };
2127
2128 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2129 g_pars.vec.sres,
2130 g_pars.vec.kc,
2131 g_pars.vec.ik,
2132 g_pars.vec.ck,
2133 g_pars.vec.autn,
2134 g_pars.vec.res));
2135 /* send new key material */
2136 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2137
2138 /* wait for the new Auth Request */
2139 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2140 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2141 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2142 l3_mt := bd.l3_mt;
2143 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2144 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2145 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2146 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2147 valueField := substr(g_pars.vec.res, 0, 4)
2148 };
2149 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2150 elementIdentifier := '21'O,
2151 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2152 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2153 };
2154 l3_mo := valueof(auth_ciph_resp);
2155 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2156 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2157 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2158 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2159 }
2160 f_send_l3_gmm_llc(l3_mo);
2161 deactivate(di);
2162
2163 /* Expect SGSN to perform LU with HLR */
2164 f_gmm_gsup_lu_isd();
2165
2166 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2167 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2168 }
2169 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2170 setverdict(pass);
2171}
2172
2173testcase TC_attach_usim_resync() runs on test_CT {
2174 /* MS -> SGSN: Attach Request
2175 * MS <- SGSN: Identity Request IMSI
2176 * MS -> SGSN: Identity Response IMSI
2177 * MS <- SGSN: Identity Request IMEI
2178 * MS -> SGSN: Identity Response IMEI
2179 * HLR<- SGSN: SAI Request
2180 * HLR-> SGSN: SAI Response
2181 * MS <- SGSN: Auth Request
2182 * MS -> SGSN: Auth Failure (with AUTS)
2183 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2184 * HLR-> SGSN: SAI Response (new key material)
2185 * MS <- SGSN: Auth Request (new key material)
2186 * MS -> SGSN: Auth Response
2187 * MS <- SGSN: Attach Accept
2188 * MS -> SGSN: Attach Complete
2189 */
2190 var BSSGP_ConnHdlr vc_conn;
2191 f_init();
2192 f_sleep(1.0);
2193 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2194 vc_conn.done;
2195}
2196
Harald Weltea05b8072019-04-23 22:35:05 +02002197
2198/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2199private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2200 f_gmm_attach(false, false);
2201 f_sleep(1.0);
2202 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2203 /* try to detach to check if SGSN is still alive */
2204 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2205}
2206testcase TC_llc_null() runs on test_CT {
2207 var BSSGP_ConnHdlr vc_conn;
2208 f_init();
2209 f_sleep(1.0);
2210 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2211 vc_conn.done;
2212}
2213
Harald Welte645a1512019-04-23 23:18:23 +02002214/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2215private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2216 f_gmm_attach(false, false);
2217 f_sleep(1.0);
2218 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2219 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP)));
2220 setverdict(pass);
2221}
2222testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2223 var BSSGP_ConnHdlr vc_conn;
2224 f_init();
2225 f_sleep(1.0);
2226 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2227 vc_conn.done;
2228}
2229
2230/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2231private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2232 f_gmm_attach(false, false);
2233 f_sleep(1.0);
2234 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
2235 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP)));
2236 setverdict(pass);
2237}
2238testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2239 var BSSGP_ConnHdlr vc_conn;
2240 f_init();
2241 f_sleep(1.0);
2242 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2243 vc_conn.done;
2244}
2245
Harald Welte2aaac1b2019-05-02 10:02:53 +02002246/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2247private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2248 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2249 var template (value) XID_Information xid;
2250 var template XID_Information xid_rx;
2251
2252 /* first perform regular attach */
2253 f_TC_attach(id);
2254 /* then activate PDP context */
2255 f_pdp_ctx_act(apars);
2256
2257 /* start MO XID */
2258 xid := { ts_XID_L3(''O) };
2259 xid_rx := { tr_XID_L3(''O) };
2260 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2261 alt {
2262 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(xid_rx, apars.sapi)));
2263 [] as_xid(apars);
2264 }
2265 setverdict(pass);
2266}
2267testcase TC_xid_empty_l3() runs on test_CT {
2268 var BSSGP_ConnHdlr vc_conn;
2269 f_init();
2270 f_sleep(1.0);
2271 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2272 vc_conn.done;
2273}
2274
2275private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2276 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2277 var template (value) XID_Information xid;
2278 var template XID_Information xid_rx;
2279
2280 /* first perform regular attach */
2281 f_TC_attach(id);
2282 /* then activate PDP context */
2283 f_pdp_ctx_act(apars);
2284
2285 /* start MO XID */
2286 xid := { ts_XID_N201U(1234) };
2287 xid_rx := { tr_XID_N201U(1234) };
2288 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2289 alt {
2290 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi)));
2291 [] as_xid(apars);
2292 }
2293 setverdict(pass);
2294}
2295testcase TC_xid_n201u() runs on test_CT {
2296 var BSSGP_ConnHdlr vc_conn;
2297 f_init();
2298 f_sleep(1.0);
2299 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2300 vc_conn.done;
2301}
2302
Alexander Couzens6bee0872019-05-11 01:48:50 +02002303private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2304 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2305
2306 /* first perform regular attach */
2307 f_TC_attach(id);
2308 /* then activate PDP context */
2309 f_pdp_ctx_act(apars);
2310 /* do a normal detach */
2311 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2312}
2313
2314testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2315 /* MS -> SGSN: Attach Request
2316 * MS <-> SGSN: [..]
2317 * MS -> SGSN: Attach Complete
2318 * MS -> SGSN: PDP Activate Request
2319 * MS <- SGSN: PDP Activate Accept
2320 * MS -> SGSN: GMM Detach Request
2321 * MS <- SGSN: GMM Detach Accept
2322 */
2323 var BSSGP_ConnHdlr vc_conn;
2324 f_init();
2325 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2326 vc_conn.done;
2327}
Harald Welte645a1512019-04-23 23:18:23 +02002328
2329
Harald Welte5ac31492018-02-15 20:39:13 +01002330control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002331 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002332 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002333 execute( TC_attach_umts_aka_umts_res() );
2334 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002335 execute( TC_attach_auth_id_timeout() );
2336 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002337 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002338 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002339 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002340 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002341 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002342 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002343 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002344 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002345 execute( TC_attach_closed_add_vty(), 20.0 );
2346 execute( TC_attach_check_subscriber_list(), 20.0 );
2347 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002348 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002349 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2350 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2351 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2352 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002353 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002354 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002355 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002356 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002357 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002358 execute( TC_detach_unknown_nopoweroff() );
2359 execute( TC_detach_unknown_poweroff() );
2360 execute( TC_detach_nopoweroff() );
2361 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002362 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002363 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002364 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002365 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002366 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002367 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002368 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002369 execute( TC_attach_restart_ctr_echo() );
2370 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002371 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002372 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002373 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002374 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002375
Harald Welte2aaac1b2019-05-02 10:02:53 +02002376 execute( TC_xid_empty_l3() );
2377 execute( TC_xid_n201u() );
2378
Harald Weltea05b8072019-04-23 22:35:05 +02002379 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002380 execute( TC_llc_sabm_dm_llgmm() );
2381 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002382}
Harald Welte96a33b02018-02-04 10:36:22 +01002383
2384
2385
2386}