blob: 74cdece38f39e43b4ecbae84bb26fb9cfbb399e1 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
3import from General_Types all;
4import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +01005import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +01006import from NS_Types all;
7import from NS_Emulation all;
8import from BSSGP_Types all;
9import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010010import from Osmocom_Gb_Types all;
11
12import from MobileL3_CommonIE_Types all;
13import from MobileL3_GMM_SM_Types all;
14import from MobileL3_Types all;
15import from L3_Templates all;
16import from L3_Common all;
17
18import from GSUP_Emulation all;
19import from GSUP_Types all;
20import from IPA_Emulation all;
21
Harald Welteeded9ad2018-02-17 20:57:34 +010022import from GTP_Emulation all;
23import from GTP_Templates all;
24import from GTP_CodecPort all;
25import from GTPC_Types all;
26import from GTPU_Types all;
27
Harald Weltea2526a82018-02-18 19:03:36 +010028import from LLC_Types all;
29import from LLC_Templates all;
30
31import from SNDCP_Types all;
32
Harald Weltebd194722018-02-16 22:11:08 +010033import from TELNETasp_PortType all;
34import from Osmocom_VTY_Functions all;
35
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010036import from GSM_RR_Types all;
37
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020038import from MobileL3_MM_Types all;
39
Harald Welteeded9ad2018-02-17 20:57:34 +010040
Harald Welte5ac31492018-02-15 20:39:13 +010041modulepar {
42 /* IP/port on which we run our internal GSUP/HLR emulation */
43 charstring mp_hlr_ip := "127.0.0.1";
44 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010045 charstring mp_ggsn_ip := "127.0.0.2";
Alexander Couzens2c12b242018-07-31 00:30:11 +020046
Alexander Couzensf3c1b412018-08-24 00:42:51 +020047 NSConfigurations mp_nsconfig := {
48 {
49 local_udp_port := 21010,
50 local_ip := "127.0.0.1",
51 remote_udp_port := 23000,
52 remote_ip := "127.0.0.1",
53 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020054 nsei := 96,
55 role_sgsn := false,
56 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020057 },
58 {
59 local_udp_port := 21011,
60 local_ip := "127.0.0.1",
61 remote_udp_port := 23000,
62 remote_ip := "127.0.0.1",
63 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020064 nsei := 97,
65 role_sgsn := false,
66 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020067 },
68 {
69 local_udp_port := 21012,
70 local_ip := "127.0.0.1",
71 remote_udp_port := 23000,
72 remote_ip := "127.0.0.1",
73 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020074 nsei := 98,
75 role_sgsn := false,
76 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020077 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020078 };
Harald Welte5ac31492018-02-15 20:39:13 +010079};
80
81type record GbInstance {
82 NS_CT vc_NS,
83 BSSGP_CT vc_BSSGP,
84 BssgpConfig cfg
85};
Harald Welte96a33b02018-02-04 10:36:22 +010086
Alexander Couzens51114d12018-07-31 18:41:56 +020087type record length(3) of GbInstance GbInstances;
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088type record length(3) of NSConfiguration NSConfigurations;
Alexander Couzens51114d12018-07-31 18:41:56 +020089type record length(3) of BssgpCellId BssgpCellIds;
90
Harald Welte96a33b02018-02-04 10:36:22 +010091type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +020092 var GbInstances g_gb;
Harald Welte96a33b02018-02-04 10:36:22 +010093
Harald Welte5ac31492018-02-15 20:39:13 +010094 var GSUP_Emulation_CT vc_GSUP;
95 var IPA_Emulation_CT vc_GSUP_IPA;
96 /* only to get events from IPA underneath GSUP */
97 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010098
Harald Welteeded9ad2018-02-17 20:57:34 +010099 var GTP_Emulation_CT vc_GTP;
100
Harald Weltebd194722018-02-16 22:11:08 +0100101 port TELNETasp_PT SGSNVTY;
102
Harald Welte96a33b02018-02-04 10:36:22 +0100103 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200104 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100105};
106
Harald Welteeded9ad2018-02-17 20:57:34 +0100107type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100108 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100109 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200110 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100111}
112
113type record SGSN_ConnHdlrNetworkPars {
114 boolean expect_ptmsi,
115 boolean expect_auth,
116 boolean expect_ciph
117};
118
119type record BSSGP_ConnHdlrPars {
120 /* IMEI of the simulated ME */
121 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200122 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100123 hexstring imsi,
124 /* MSISDN of the simulated MS (probably unused) */
125 hexstring msisdn,
126 /* P-TMSI allocated to the simulated MS */
127 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100128 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100129 /* TLLI of the simulated MS */
130 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100131 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100132 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200133 BssgpCellIds bssgp_cell_id,
Harald Welte5ac31492018-02-15 20:39:13 +0100134 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100135 SGSN_ConnHdlrNetworkPars net,
136 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100137};
138
Alexander Couzens89508702018-07-31 04:16:10 +0200139private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200140 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200141 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
142
143 var RoutingAreaIdentificationV ret := {
144 mccDigit1 := mcc_mnc[0],
145 mccDigit2 := mcc_mnc[1],
146 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200147 mncDigit3 := mcc_mnc[3],
148 mncDigit1 := mcc_mnc[4],
149 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200150 lac := int2oct(cell_id.ra_id.lai.lac, 16),
151 rac := int2oct(cell_id.ra_id.rac, 8)
152 }
153 return ret;
154};
155
Alexander Couzens51114d12018-07-31 18:41:56 +0200156private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
157 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
158 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100159 /* connect lower end of BSSGP emulation with NS upper port */
160 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
161 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
162 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
163
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200164 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100165 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
166}
167
168private function f_init_gsup(charstring id) runs on test_CT {
169 id := id & "-GSUP";
170 var GsupOps ops := {
171 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
172 };
173
174 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
175 vc_GSUP := GSUP_Emulation_CT.create(id);
176
177 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
178 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
179 /* we use this hack to get events like ASP_IPA_EVENT_UP */
180 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
181
182 vc_GSUP.start(GSUP_Emulation.main(ops, id));
183 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
184
185 /* wait for incoming connection to GSUP port before proceeding */
186 timer T := 10.0;
187 T.start;
188 alt {
189 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
190 [] T.timeout {
191 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200192 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100193 }
194 }
195}
196
Harald Welteeded9ad2018-02-17 20:57:34 +0100197private function f_init_gtp(charstring id) runs on test_CT {
198 id := id & "-GTP";
199
200 var GtpEmulationCfg gtp_cfg := {
201 gtpc_bind_ip := mp_ggsn_ip,
202 gtpc_bind_port := GTP1C_PORT,
203 gtpu_bind_ip := mp_ggsn_ip,
204 gtpu_bind_port := GTP1U_PORT,
205 sgsn_role := false
206 };
207
208 vc_GTP := GTP_Emulation_CT.create(id);
209 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
210}
211
Harald Weltebd194722018-02-16 22:11:08 +0100212private function f_init_vty() runs on test_CT {
213 map(self:SGSNVTY, system:SGSNVTY);
214 f_vty_set_prompts(SGSNVTY);
215 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200216 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100217 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
218}
219
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200220private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
221 if (enable) {
222 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
223 } else {
224 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
225 }
226}
227
Harald Weltebd194722018-02-16 22:11:08 +0100228
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200229/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
230function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100231 if (g_initialized == true) {
232 return;
233 }
234 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100235 g_gb[0].cfg := {
236 nsei := 96,
237 bvci := 196,
238 cell_id := {
239 ra_id := {
240 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100241 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100242 rac := 0
243 },
244 cell_id := 20960
245 },
246 sgsn_role := false
247 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200248 g_gb[1].cfg := {
249 nsei := 97,
250 bvci := 210,
251 cell_id := {
252 ra_id := {
253 lai := {
254 mcc_mnc := mcc_mnc, lac := 13200},
255 rac := 0
256 },
257 cell_id := 20961
258 },
259 sgsn_role := false
260 };
261 g_gb[2].cfg := {
262 nsei := 98,
263 bvci := 220,
264 cell_id := {
265 ra_id := {
266 lai := {
267 mcc_mnc := mcc_mnc, lac := 13300},
268 rac := 0
269 },
270 cell_id := 20962
271 },
272 sgsn_role := false
273 };
Harald Welte96a33b02018-02-04 10:36:22 +0100274
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200275 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200276 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
277 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
278 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte5ac31492018-02-15 20:39:13 +0100279 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100280 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200281 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100282}
Harald Welte96a33b02018-02-04 10:36:22 +0100283
Harald Welte5ac31492018-02-15 20:39:13 +0100284type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
285
286/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200287function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100288 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100289runs on test_CT return BSSGP_ConnHdlr {
290 var BSSGP_ConnHdlr vc_conn;
291 var SGSN_ConnHdlrNetworkPars net_pars := {
292 expect_ptmsi := true,
293 expect_auth := true,
294 expect_ciph := false
295 };
296 var BSSGP_ConnHdlrPars pars := {
297 imei := f_gen_imei(imsi_suffix),
298 imsi := f_gen_imsi(imsi_suffix),
299 msisdn := f_gen_msisdn(imsi_suffix),
300 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100301 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100302 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100303 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100304 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200305 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 +0100306 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100307 net := net_pars,
308 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100309 };
310
311 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200312 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
313 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
314 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
315 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
316 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
317 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100318
319 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
320 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
321
Harald Welteeded9ad2018-02-17 20:57:34 +0100322 connect(vc_conn:GTP, vc_GTP:CLIENT);
323 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
324
Harald Welte5ac31492018-02-15 20:39:13 +0100325 vc_conn.start(f_handler_init(fn, id, pars));
326 return vc_conn;
327}
328
Harald Welte62e29582018-02-16 21:17:11 +0100329private altstep as_Tguard() runs on BSSGP_ConnHdlr {
330 [] g_Tguard.timeout {
331 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200332 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100333 }
334}
335
Harald Welte5ac31492018-02-15 20:39:13 +0100336/* first function called in every ConnHdlr */
337private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
338runs on BSSGP_ConnHdlr {
339 /* do some common stuff like setting up g_pars */
340 g_pars := pars;
341
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200342 llc := f_llc_create(false);
343
Harald Welte5ac31492018-02-15 20:39:13 +0100344 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200345 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100346 /* tell GSUP dispatcher to send this IMSI to us */
347 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100348 /* tell GTP dispatcher to send this IMSI to us */
349 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100350
Harald Welte62e29582018-02-16 21:17:11 +0100351 g_Tguard.start(pars.t_guard);
352 activate(as_Tguard());
353
Harald Welte5ac31492018-02-15 20:39:13 +0100354 /* call the user-supplied test case function */
355 fn.apply(id);
356 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100357}
358
359/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100360 * Detach without Attach
361 * SM procedures without attach / RAU
362 * ATTACH / RAU
363 ** with / without authentication
364 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100365 * re-transmissions of LLC frames
366 * PDP Context activation
367 ** with different GGSN config in SGSN VTY
368 ** with different PDP context type (v4/v6/v46)
369 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100370 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100371 */
372
373testcase TC_wait_ns_up() runs on test_CT {
374 f_init();
375 f_sleep(20.0);
376}
377
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200378function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
379 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
380 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
381 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
382 var octetstring llc_enc := enc_PDU_LLC(valueof(ts_LLC_UI(l3_enc, sapi, '0'B, n_u)));
383 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
384}
385
Harald Welte5ac31492018-02-15 20:39:13 +0100386altstep as_mm_identity() runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100387 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200388 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100389 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200390 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100391 repeat;
392 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200393 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100394 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200395 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100396 repeat;
397 }
398}
Harald Welte96a33b02018-02-04 10:36:22 +0100399
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200400/* perform GMM authentication (if expected).
401 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
402 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
403function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100404 var BssgpDecoded bd;
405 var PDU_L3_MS_SGSN l3_mo;
406 var PDU_L3_SGSN_MS l3_mt;
407 var default di := activate(as_mm_identity());
408 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200409 var GSUP_IE auth_tuple;
410 var template AuthenticationParameterAUTNTLV autn;
411
412 if (umts_aka_challenge) {
413 g_pars.vec := f_gen_auth_vec_3g();
414 autn := {
415 elementIdentifier := '28'O,
416 lengthIndicator := lengthof(g_pars.vec.autn),
417 autnValue := g_pars.vec.autn
418 };
419
420 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
421 g_pars.vec.sres,
422 g_pars.vec.kc,
423 g_pars.vec.ik,
424 g_pars.vec.ck,
425 g_pars.vec.autn,
426 g_pars.vec.res));
427 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
428 } else {
429 g_pars.vec := f_gen_auth_vec_2g();
430 autn := omit;
431 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
432 g_pars.vec.sres,
433 g_pars.vec.kc));
434 log("GSUP sends only 2G auth tuple", auth_tuple);
435 }
Harald Welte5ac31492018-02-15 20:39:13 +0100436 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
437 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200438
439 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
440 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200441 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
Harald Welte5ac31492018-02-15 20:39:13 +0100442 l3_mt := bd.l3_mt;
443 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200444 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
445
446 if (umts_aka_challenge and not force_gsm_sres) {
447 /* set UMTS response instead */
448 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
449 valueField := substr(g_pars.vec.res, 0, 4)
450 };
451 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
452 elementIdentifier := '21'O,
453 lengthIndicator := lengthof(g_pars.vec.res) - 4,
454 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
455 };
456 }
457
458 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100459 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
460 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
461 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
462 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
463 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200464 f_send_l3_gmm_llc(l3_mo);
Harald Welte76dee092018-02-16 22:12:59 +0100465 } else {
466 /* wait for identity procedure */
467 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100468 }
Harald Welte76dee092018-02-16 22:12:59 +0100469
Harald Welte5ac31492018-02-15 20:39:13 +0100470 deactivate(di);
471}
472
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200473function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100474 g_pars.p_tmsi := p_tmsi;
475 /* update TLLI */
476 g_pars.tlli_old := g_pars.tlli;
477 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200478 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100479}
480
Harald Welte04683d02018-02-16 22:43:45 +0100481function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
482 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100483 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200484 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100485 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200486 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200487 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100488 }
Harald Welte04683d02018-02-16 22:43:45 +0100489 g_pars.ra := aa.routingAreaIdentification;
490 if (ispresent(aa.allocatedPTMSI)) {
491 if (not g_pars.net.expect_ptmsi) {
492 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200493 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100494 }
Harald Weltef70997d2018-02-17 10:11:19 +0100495 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100496 }
497 if (ispresent(aa.msIdentity)) {
498 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200499 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100500 }
501 /* P-TMSI.sig */
502 if (ispresent(aa.ptmsiSignature)) {
503 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
504 }
505 /* updateTimer */
506 // aa.readyTimer
507 /* T3302, T3319, T3323, T3312_ext, T3324 */
508}
509
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200510function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100511 /* mandatory IE */
512 g_pars.ra := ra.routingAreaId;
513 if (ispresent(ra.allocatedPTMSI)) {
514 if (not g_pars.net.expect_ptmsi) {
515 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200516 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100517 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200518 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100519 }
520 if (ispresent(ra.msIdentity)) {
521 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200522 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100523 }
524 /* P-TMSI.sig */
525 if (ispresent(ra.ptmsiSignature)) {
526 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
527 }
528 /* updateTimer */
529 // aa.readyTimer
530 /* T3302, T3319, T3323, T3312_ext, T3324 */
531}
532
533
Harald Welte5a4fa042018-02-16 20:59:21 +0100534function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
535 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
536}
537
Harald Welte23178c52018-02-17 09:36:33 +0100538/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100539private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100540 if (ispresent(g_pars.p_tmsi)) {
541 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
542 } else {
543 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
544 }
545}
546
Harald Welte311ec272018-02-17 09:40:03 +0100547private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100548 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100549 /* Expect MSC to perform LU with HLR */
550 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100551 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
552 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
553 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100554 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
555 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
556}
557
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200558private function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100559 var BssgpDecoded bd;
Harald Welte5a4fa042018-02-16 20:59:21 +0100560 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200561 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welte5ac31492018-02-15 20:39:13 +0100562
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200563 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
564 * 3G auth vectors */
565 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
566 /* The thing is, if the solSACapability is 'omit', then the
567 * revisionLevelIndicatior is at the wrong place! */
568 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
569
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200570 f_send_l3_gmm_llc(attach_req);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200571 f_gmm_auth(umts_aka_challenge, force_gsm_sres);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200572 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100573 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100574
Alexander Couzens0e510e62018-07-28 23:06:00 +0200575 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100576 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
577 }
578 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200579 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200580}
581
582private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
583 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100584 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100585}
586
587testcase TC_attach() runs on test_CT {
588 var BSSGP_ConnHdlr vc_conn;
589 f_init();
590 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200591 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100592 vc_conn.done;
593}
594
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100595testcase TC_attach_mnc3() runs on test_CT {
596 var BSSGP_ConnHdlr vc_conn;
597 f_init('023042'H);
598 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200599 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100600 vc_conn.done;
601}
602
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200603private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
604 f_gmm_attach(true, false);
605 setverdict(pass);
606}
607testcase TC_attach_umts_aka_umts_res() runs on test_CT {
608 var BSSGP_ConnHdlr vc_conn;
609 f_init();
610 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200611 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200612 vc_conn.done;
613}
614
615private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
616 f_gmm_attach(true, true);
617 setverdict(pass);
618}
619testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
620 var BSSGP_ConnHdlr vc_conn;
621 f_init();
622 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200623 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200624 vc_conn.done;
625}
626
Harald Welte5b7c8122018-02-16 21:48:17 +0100627/* MS never responds to ID REQ, expect ATTACH REJECT */
628private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100629 var RoutingAreaIdentificationV old_ra := f_random_RAI();
630
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200631 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 +0100632 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200633 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100634 /* don't send ID Response */
635 repeat;
636 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200637 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100638 setverdict(pass);
639 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200640 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100641 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200642 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100643 }
644 }
645}
646testcase TC_attach_auth_id_timeout() runs on test_CT {
647 var BSSGP_ConnHdlr vc_conn;
648 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200649 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 +0100650 vc_conn.done;
651}
652
653/* HLR never responds to SAI REQ, expect ATTACH REJECT */
654private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100655 var RoutingAreaIdentificationV old_ra := f_random_RAI();
656
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200657 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 +0100658 alt {
659 [] as_mm_identity();
660 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
661 }
662 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200663 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100664 setverdict(pass);
665}
666testcase TC_attach_auth_sai_timeout() runs on test_CT {
667 var BSSGP_ConnHdlr vc_conn;
668 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200669 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100670 vc_conn.done;
671}
672
Harald Weltefe253882018-02-17 09:25:00 +0100673/* HLR rejects SAI, expect ATTACH REJECT */
674private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100675 var RoutingAreaIdentificationV old_ra := f_random_RAI();
676
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200677 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 +0100678 alt {
679 [] as_mm_identity();
680 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
681 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
682 }
683 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200684 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100685 setverdict(pass);
686}
687testcase TC_attach_auth_sai_reject() runs on test_CT {
688 var BSSGP_ConnHdlr vc_conn;
689 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200690 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100691 vc_conn.done;
692}
693
Harald Welte5b7c8122018-02-16 21:48:17 +0100694/* HLR never responds to UL REQ, expect ATTACH REJECT */
695private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100696 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100697 var RoutingAreaIdentificationV old_ra := f_random_RAI();
698
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200699 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 +0100700 f_gmm_auth();
701 /* Expect MSC to perform LU with HLR */
702 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
703 /* Never follow-up with ISD_REQ or UL_RES */
704 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200705 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100706 setverdict(pass);
707 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200708 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100709 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100710 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200711 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100712 }
713 }
714}
715testcase TC_attach_gsup_lu_timeout() runs on test_CT {
716 var BSSGP_ConnHdlr vc_conn;
717 f_init();
718 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200719 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100720 vc_conn.done;
721}
722
Harald Welteb7c14e92018-02-17 09:29:16 +0100723/* HLR rejects UL REQ, expect ATTACH REJECT */
724private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
725 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100726 var RoutingAreaIdentificationV old_ra := f_random_RAI();
727
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200728 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 +0100729 f_gmm_auth();
730 /* Expect MSC to perform LU with HLR */
731 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
732 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
733 }
734 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200735 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100736 setverdict(pass);
737 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200738 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100739 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
740 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200741 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100742 }
743 }
744}
745testcase TC_attach_gsup_lu_reject() runs on test_CT {
746 var BSSGP_ConnHdlr vc_conn;
747 f_init();
748 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200749 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100750 vc_conn.done;
751}
752
753
Harald Welte3823e2e2018-02-16 21:53:48 +0100754/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
755private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100756 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100757 var RoutingAreaIdentificationV old_ra := f_random_RAI();
758
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200759 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 +0100760 f_gmm_auth();
761 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100762 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100763
Alexander Couzens0e510e62018-07-28 23:06:00 +0200764 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100765 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
766 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200767 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100768 setverdict(pass);
769}
Harald Welte3823e2e2018-02-16 21:53:48 +0100770testcase TC_attach_combined() runs on test_CT {
771 var BSSGP_ConnHdlr vc_conn;
772 f_init();
773 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200774 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100775 vc_conn.done;
776}
777
Harald Welte76dee092018-02-16 22:12:59 +0100778/* Attempt of GPRS ATTACH in 'accept all' mode */
779private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100780 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100781 var RoutingAreaIdentificationV old_ra := f_random_RAI();
782
783 g_pars.net.expect_auth := false;
784
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200785 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 +0100786 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200787 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100788 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
789 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200790 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100791 setverdict(pass);
792}
793testcase TC_attach_accept_all() runs on test_CT {
794 var BSSGP_ConnHdlr vc_conn;
795 f_init();
796 f_sleep(1.0);
797 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200798 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100799 vc_conn.done;
800}
Harald Welte5b7c8122018-02-16 21:48:17 +0100801
Harald Welteb2124b22018-02-16 22:26:56 +0100802/* Attempt of GPRS ATTACH in 'accept all' mode */
803private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100804 var RoutingAreaIdentificationV old_ra := f_random_RAI();
805
806 /* Simulate a foreign IMSI */
807 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200808 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100809
810 g_pars.net.expect_auth := false;
811
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200812 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 +0100813 alt {
814 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200815 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100816 setverdict(pass);
817 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200818 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100819 setverdict(pass);
820 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200821 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200822 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200823 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200824 }
Harald Welteb2124b22018-02-16 22:26:56 +0100825 }
826}
827testcase TC_attach_closed() runs on test_CT {
828 var BSSGP_ConnHdlr vc_conn;
829 f_init();
830 f_sleep(1.0);
831 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
832 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200833 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100834 vc_conn.done;
835 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200836 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100837 vc_conn.done;
838}
839
Harald Welte04683d02018-02-16 22:43:45 +0100840/* Routing Area Update from Unknown TLLI -> REJECT */
841private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100842 var RoutingAreaIdentificationV old_ra := f_random_RAI();
843
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200844 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 +0100845 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200846 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100847 setverdict(pass);
848 }
849 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200850 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100851 }
852}
853testcase TC_rau_unknown() runs on test_CT {
854 var BSSGP_ConnHdlr vc_conn;
855 f_init();
856 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200857 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100858 vc_conn.done;
859}
860
Harald Welte91636de2018-02-17 10:16:14 +0100861private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
862 var BssgpDecoded bd;
863
864 /* first perform regular attach */
865 f_TC_attach(id);
866
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200867 f_routing_area_update(g_pars.ra);
868
Harald Welte91636de2018-02-17 10:16:14 +0100869}
870testcase TC_attach_rau() runs on test_CT {
871 var BSSGP_ConnHdlr vc_conn;
872 f_init();
873 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200874 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100875 vc_conn.done;
876}
Harald Welte04683d02018-02-16 22:43:45 +0100877
Harald Welte6abb9fe2018-02-17 15:24:48 +0100878/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200879function 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 +0100880 var BssgpDecoded bd;
881 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200882 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100883 if (expect_purge) {
884 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
885 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
886 }
887 T.start;
888 alt {
889 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
890 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200891 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100892 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200893 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100894 g_pars.ra := omit;
895 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200896 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100897 /* TODO: check if any PDP contexts are deactivated on network side? */
898 }
899 [power_off] T.timeout {
900 setverdict(pass);
901 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200902 [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 +0100903 g_pars.ra := omit;
904 setverdict(pass);
905 /* TODO: check if any PDP contexts are deactivated on network side? */
906 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200907 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100908 }
909}
910
911/* IMSI DETACH (non-power-off) for unknown TLLI */
912private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
913 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
914}
915testcase TC_detach_unknown_nopoweroff() runs on test_CT {
916 var BSSGP_ConnHdlr vc_conn;
917 f_init();
918 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200919 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100920 vc_conn.done;
921}
922
923/* IMSI DETACH (power-off) for unknown TLLI */
924private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
925 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
926}
927testcase TC_detach_unknown_poweroff() runs on test_CT {
928 var BSSGP_ConnHdlr vc_conn;
929 f_init();
930 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200931 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100932 vc_conn.done;
933}
934
935/* IMSI DETACH (non-power-off) for known TLLI */
936private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
937 /* first perform regular attach */
938 f_TC_attach(id);
939
940 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
941}
942testcase TC_detach_nopoweroff() runs on test_CT {
943 var BSSGP_ConnHdlr vc_conn;
944 f_init();
945 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200946 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100947 vc_conn.done;
948}
949
950/* IMSI DETACH (power-off) for known TLLI */
951private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
952 /* first perform regular attach */
953 f_TC_attach(id);
954
955 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
956}
957testcase TC_detach_poweroff() runs on test_CT {
958 var BSSGP_ConnHdlr vc_conn;
959 f_init();
960 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200961 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100962 vc_conn.done;
963}
964
Harald Welteeded9ad2018-02-17 20:57:34 +0100965type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100966 BIT3 tid, /* L3 Transaction ID */
967 BIT4 nsapi, /* SNDCP NSAPI */
968 BIT4 sapi, /* LLC SAPI */
969 QoSV qos, /* QoS parameters */
970 PDPAddressV addr, /* IP address */
971 octetstring apn optional, /* APN name */
972 ProtocolConfigOptionsV pco optional, /* protoco config opts */
973 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100974 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100975 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100976
Harald Welte822f9102018-02-18 20:39:06 +0100977 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
978 OCT4 ggsn_tei_u, /* GGSN TEI User */
979 octetstring ggsn_ip_c, /* GGSN IP Control */
980 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200981 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100982
Harald Welte822f9102018-02-18 20:39:06 +0100983 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
984 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
985 octetstring sgsn_ip_c optional, /* SGSN IP Control */
986 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100987};
988
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100989
990private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
991 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
992 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
993 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
994 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
995 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
996 f_gtp_register_teid(apars.ggsn_tei_c);
997 f_gtp_register_teid(apars.ggsn_tei_u);
998}
999
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001000function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001001 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1002 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001003 var template Recovery_gtpc recovery := omit;
1004
1005 if (send_recovery) {
1006 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1007 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001008
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001009 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welteeded9ad2018-02-17 20:57:34 +01001010 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001011 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1012 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1013 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1014 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1015 apars.sgsn_tei_c, apars.gtp_resp_cause,
1016 apars.ggsn_tei_c, apars.ggsn_tei_u,
1017 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001018 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1019 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001020 }
1021 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001022 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001023 setverdict(pass);
1024 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001025 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001026 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001027 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001028 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001029 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001030 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001031 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001032 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001033 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001034 setverdict(pass);
1035 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001036 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +01001037 }
1038}
1039
Harald Welte6f203162018-02-18 22:04:55 +01001040function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
1041 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1042 var Gtp1cUnitdata g_ud;
1043
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001044 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
Harald Welte6f203162018-02-18 22:04:55 +01001045 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1046 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001047 BSSGP[0].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001048 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1049 }
1050 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001051 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001052 setverdict(pass);
1053 }
1054 [] as_xid(apars);
1055 }
1056}
1057
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001058function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001059 var Gtp1cUnitdata g_ud;
1060 var integer seq_nr := 23;
1061 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1062
Alexander Couzens0e510e62018-07-28 23:06:00 +02001063 BSSGP[0].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001064 if (error_ind) {
1065 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1066 } else {
1067 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1068 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001069
1070 timer T := 5.0;
1071 T.start;
1072
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001073 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001074 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001075 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Harald Welte57b9b7f2018-02-18 22:28:13 +01001076 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001077 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1078 repeat;
1079 }
1080 [] T.timeout {
1081 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1082 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001083 }
1084}
1085
Harald Welte6f203162018-02-18 22:04:55 +01001086
Harald Welteeded9ad2018-02-17 20:57:34 +01001087/* Table 10.5.156/3GPP TS 24.008 */
1088template (value) QoSV t_QosDefault := {
1089 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1090 delayClass := '100'B, /* best effort */
1091 spare1 := '00'B,
1092 precedenceClass := '010'B, /* normal */
1093 spare2 := '0'B,
1094 peakThroughput := '0000'B, /* subscribed */
1095 meanThroughput := '00000'B, /* subscribed */
1096 spare3 := '000'B,
1097 deliverErroneusSDU := omit,
1098 deliveryOrder := omit,
1099 trafficClass := omit,
1100 maxSDUSize := omit,
1101 maxBitrateUplink := omit,
1102 maxBitrateDownlink := omit,
1103 sduErrorRatio := omit,
1104 residualBER := omit,
1105 trafficHandlingPriority := omit,
1106 transferDelay := omit,
1107 guaranteedBitRateUplink := omit,
1108 guaranteedBitRateDownlink := omit,
1109 sourceStatisticsDescriptor := omit,
1110 signallingIndication := omit,
1111 spare4 := omit,
1112 maxBitrateDownlinkExt := omit,
1113 guaranteedBitRateDownlinkExt := omit,
1114 maxBitrateUplinkExt := omit,
1115 guaranteedBitRateUplinkExt := omit,
1116 maxBitrateDownlinkExt2 := omit,
1117 guaranteedBitRateDownlinkExt2 := omit,
1118 maxBitrateUplinkExt2 := omit,
1119 guaranteedBitRateUplinkExt2 := omit
1120}
1121
1122/* 10.5.6.4 / 3GPP TS 24.008 */
1123template (value) PDPAddressV t_AddrIPv4dyn := {
1124 pdpTypeOrg := '0001'B, /* IETF */
1125 spare := '0000'B,
1126 pdpTypeNum := '21'O, /* IPv4 */
1127 addressInfo := omit
1128}
1129template (value) PDPAddressV t_AddrIPv6dyn := {
1130 pdpTypeOrg := '0001'B, /* IETF */
1131 spare := '0000'B,
1132 pdpTypeNum := '53'O, /* IPv6 */
1133 addressInfo := omit
1134}
1135
Harald Welte37692d82018-02-18 15:21:34 +01001136template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001137 tid := '000'B,
1138 nsapi := '0101'B, /* < 5 are reserved */
1139 sapi := '0011'B, /* 3/5/9/11 */
1140 qos := t_QosDefault,
1141 addr := t_AddrIPv4dyn,
1142 apn := omit,
1143 pco := omit,
1144 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001145 gtp_resp_cause := int2oct(128, 1),
1146 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001147
1148 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001149 ggsn_tei_c := f_rnd_octstring(4),
1150 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001151 ggsn_ip_c := f_inet_addr(ggsn_ip),
1152 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001153 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001154
Harald Welteeded9ad2018-02-17 20:57:34 +01001155 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001156 sgsn_tei_u := omit,
1157 sgsn_ip_c := omit,
1158 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001159}
1160
Harald Welte37692d82018-02-18 15:21:34 +01001161template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1162 connId := 1,
1163 remName := f_inet_ntoa(ip),
1164 remPort := GTP1U_PORT
1165}
1166
1167template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1168 connId := 1,
1169 remName := f_inet_ntoa(ip),
1170 remPort := GTP1C_PORT
1171}
1172
1173private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1174 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1175 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1176}
1177
1178private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001179 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001180 repeat;
1181 }
1182}
1183
1184template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1185 pDU_SN_UNITDATA := {
1186 nsapi := nsapi,
1187 moreBit := ?,
1188 snPduType := '1'B,
1189 firstSegmentIndicator := ?,
1190 spareBit := ?,
1191 pcomp := ?,
1192 dcomp := ?,
1193 npduNumber := ?,
1194 segmentNumber := ?,
1195 npduNumberContinued := ?,
1196 dataSegmentSnUnitdataPdu := payload
1197 }
1198}
1199
1200/* simple case: single segment, no compression */
1201template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1202 pDU_SN_UNITDATA := {
1203 nsapi := nsapi,
1204 moreBit := '0'B,
1205 snPduType := '1'B,
1206 firstSegmentIndicator := '1'B,
1207 spareBit := '0'B,
1208 pcomp := '0000'B,
1209 dcomp := '0000'B,
1210 npduNumber := '0000'B,
1211 segmentNumber := '0000'B,
1212 npduNumberContinued := '00'O,
1213 dataSegmentSnUnitdataPdu := payload
1214 }
1215}
1216
1217/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1218private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1219 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1220 f_gtpu_send(apars, payload);
1221 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1222 alt {
1223 [] as_xid(apars);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001224 [] BSSGP[0].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001225 }
1226}
1227
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001228/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001229private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1230 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1231 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1232 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001233 BSSGP[0].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001234 /* Expect PDU via GTP from SGSN on simulated GGSN */
1235 alt {
1236 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1237 }
1238}
1239
Harald Welteeded9ad2018-02-17 20:57:34 +01001240private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001241 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001242
1243 /* first perform regular attach */
1244 f_TC_attach(id);
1245
1246 f_pdp_ctx_act(apars);
1247}
1248testcase TC_attach_pdp_act() runs on test_CT {
1249 var BSSGP_ConnHdlr vc_conn;
1250 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001251 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001252 vc_conn.done;
1253}
Harald Welteb2124b22018-02-16 22:26:56 +01001254
Harald Welte835b15f2018-02-18 14:39:11 +01001255/* PDP Context activation for not-attached subscriber; expect fail */
1256private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001257 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001258 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 +01001259 apars.apn, apars.pco));
1260 alt {
1261 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001262 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001263 setverdict(pass);
1264 }
1265 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1266 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001267 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001268 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001269 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001270 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001271 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001272 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001273 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001274 }
1275}
1276testcase TC_pdp_act_unattached() runs on test_CT {
1277 var BSSGP_ConnHdlr vc_conn;
1278 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001279 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001280 vc_conn.done;
1281}
1282
Harald Welte37692d82018-02-18 15:21:34 +01001283/* ATTACH + PDP CTX ACT + user plane traffic */
1284private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1285 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1286
1287 /* first perform regular attach */
1288 f_TC_attach(id);
1289 /* then activate PDP context */
1290 f_pdp_ctx_act(apars);
1291 /* then transceive a downlink PDU */
1292 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1293 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1294}
1295testcase TC_attach_pdp_act_user() runs on test_CT {
1296 var BSSGP_ConnHdlr vc_conn;
1297 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001298 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001299 vc_conn.done;
1300}
1301
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001302/* ATTACH + PDP CTX ACT; reject from GGSN */
1303private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1304 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1305
1306 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1307 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1308
1309 /* first perform regular attach */
1310 f_TC_attach(id);
1311 /* then activate PDP context */
1312 f_pdp_ctx_act(apars);
1313}
1314testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1315 var BSSGP_ConnHdlr vc_conn;
1316 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001317 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001318 vc_conn.done;
1319}
Harald Welte835b15f2018-02-18 14:39:11 +01001320
Harald Welte6f203162018-02-18 22:04:55 +01001321/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1322private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1323 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1324
1325 /* first perform regular attach */
1326 f_TC_attach(id);
1327 /* then activate PDP context */
1328 f_pdp_ctx_act(apars);
1329 /* then transceive a downlink PDU */
1330 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1331 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1332
1333 f_pdp_ctx_deact_mo(apars, '00'O);
1334}
1335testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1336 var BSSGP_ConnHdlr vc_conn;
1337 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001338 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 +01001339 vc_conn.done;
1340}
1341
Harald Welte57b9b7f2018-02-18 22:28:13 +01001342/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1343private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1344 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1345
1346 /* first perform regular attach */
1347 f_TC_attach(id);
1348 /* then activate PDP context */
1349 f_pdp_ctx_act(apars);
1350 /* then transceive a downlink PDU */
1351 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1352 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1353
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001354 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001355}
1356testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1357 var BSSGP_ConnHdlr vc_conn;
1358 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001359 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 +01001360 vc_conn.done;
1361}
1362
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001363/* ATTACH + ATTACH (2nd) */
1364private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1365 g_pars.t_guard := 5.0;
1366
1367 /* first perform regular attach */
1368 f_TC_attach(id);
1369
1370 /* second to perform regular attach */
1371 f_TC_attach(id);
1372}
1373
1374
1375testcase TC_attach_second_attempt() runs on test_CT {
1376 var BSSGP_ConnHdlr vc_conn;
1377 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001378 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001379 vc_conn.done;
1380}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001381
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001382private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001383 var Gtp1cUnitdata g_ud;
1384 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1385
1386 /* first perform regular attach */
1387 f_TC_attach(id);
1388 /* Activate a pdp context against the GGSN */
1389 f_pdp_ctx_act(apars);
1390 /* Wait to receive first echo request and send initial Restart counter */
1391 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1392 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1393 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1394 }
1395 /* Wait to receive second echo request and send incremented Restart
1396 counter. This will fake a restarted GGSN, and pdp ctx allocated
1397 should be released by SGSN */
1398 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1399 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1400 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1401 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1402 }
1403 var OCT1 cause_network_failure := int2oct(38, 1)
1404 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001405 [] 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 +02001406 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001407 setverdict(pass);
1408 }
1409 [] as_xid(apars);
1410 }
1411 setverdict(pass);
1412}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001413/* ATTACH + trigger Recovery procedure through EchoResp */
1414testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001415 var BSSGP_ConnHdlr vc_conn;
1416 g_use_echo := true
1417 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001418 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 +02001419 vc_conn.done;
1420 g_use_echo := false
1421}
1422
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001423private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1424 var Gtp1cUnitdata g_ud;
1425 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1426 var integer seq_nr := 23;
1427 var GtpPeer peer;
1428 /* first perform regular attach */
1429 f_TC_attach(id);
1430
1431 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1432 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1433 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1434 f_pdp_ctx_act(apars, true);
1435
1436 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1437/* received. */
1438 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1439
1440 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1441 would be great to have an active pdp context here before triggering
1442 Recovery, and making sure the the DEACT request is sent by the SGSN.
1443 */
1444
1445 /* Activate a pdp context against the GGSN, send incremented Recovery
1446 IE. This should trigger the recovery path, but still this specific
1447 CTX activation should work. */
1448 apars.exp_rej_cause := omit; /* default value for tests */
1449 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1450 f_pdp_ctx_act(apars, true);
1451
1452 setverdict(pass);
1453}
1454/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1455testcase TC_attach_restart_ctr_create() runs on test_CT {
1456 var BSSGP_ConnHdlr vc_conn;
1457 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001458 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 +02001459 vc_conn.done;
1460}
1461
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001462/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1463private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1464 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1465 var integer seq_nr := 23;
1466 var GtpPeer peer;
1467 var integer i;
1468
1469 /* first perform regular attach */
1470 f_TC_attach(id);
1471 /* then activate PDP context */
1472 f_pdp_ctx_act(apars);
1473
Alexander Couzens0e510e62018-07-28 23:06:00 +02001474 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001475 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1476 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1477
1478 for (i := 0; i < 5; i := i+1) {
1479 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001480 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001481 [] as_xid(apars);
1482 }
1483 }
1484
1485 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1486
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001487 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001488 setverdict(pass);
1489}
1490testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1491 var BSSGP_ConnHdlr vc_conn;
1492 f_init();
1493 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001494 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 +02001495 vc_conn.done;
1496}
1497
Alexander Couzens5e307b42018-05-22 18:12:20 +02001498private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1499 /* MS: perform regular attach */
1500 f_TC_attach(id);
1501
1502 /* HLR: cancel the location request */
1503 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1504 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001505
1506 /* ensure no Detach Request got received */
1507 timer T := 5.0;
1508 T.start;
1509 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001510 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001511 T.stop;
1512 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001513 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001514 }
1515 [] T.timeout {
1516 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001517 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001518 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001519 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001520 repeat;
1521 }
1522 }
1523}
1524
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001525/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1526private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1527 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1528
1529 /* first perform regular attach */
1530 f_TC_attach(id);
1531 /* then activate PDP context */
1532 f_pdp_ctx_act(apars);
1533 /* then transceive a downlink PDU */
1534 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1535
1536 /* Send Error indication as response from upload PDU and expect deact towards MS */
1537 f_pdp_ctx_deact_mt(apars, true);
1538}
1539testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1540 var BSSGP_ConnHdlr vc_conn;
1541 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001542 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 +02001543 vc_conn.done;
1544}
1545
Alexander Couzens5e307b42018-05-22 18:12:20 +02001546testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1547 /* MS <-> SGSN: GMM Attach
1548 * HLR -> SGSN: Cancel Location Request
1549 * HLR <- SGSN: Cancel Location Ack
1550 */
1551 var BSSGP_ConnHdlr vc_conn;
1552 f_init();
1553 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001554 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001555 vc_conn.done;
1556}
1557
1558
Alexander Couzensc87967a2018-05-22 16:09:54 +02001559private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1560 /* MS: perform regular attach */
1561 f_TC_attach(id);
1562
1563 /* HLR: cancel the location request */
1564 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1565 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1566 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1567
1568 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001569 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 +02001570 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001571
1572 setverdict(pass);
1573}
1574
1575testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1576 /* MS <-> SGSN: GMM Attach
1577 * HLR -> SGSN: Cancel Location Request
1578 * HLR <- SGSN: Cancel Location Ack
1579 * MS <- SGSN: Detach Request
1580 * SGSN-> MS: Detach Complete
1581 */
1582 var BSSGP_ConnHdlr vc_conn;
1583 f_init();
1584 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001585 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001586 vc_conn.done;
1587}
1588
1589
Alexander Couzens6c47f292018-05-22 17:09:49 +02001590private function f_hlr_location_cancel_request_unknown_subscriber(
1591 charstring id,
1592 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1593
1594 /* HLR: cancel the location request */
1595 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1596
1597 /* cause 2 = IMSI_UNKNOWN */
1598 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1599
1600 setverdict(pass);
1601}
1602
1603private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001604 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001605}
1606
1607testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1608 /* HLR -> SGSN: Cancel Location Request
1609 * HLR <- SGSN: Cancel Location Error
1610 */
1611
1612 var BSSGP_ConnHdlr vc_conn;
1613 f_init();
1614 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001615 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 +02001616 vc_conn.done;
1617}
1618
1619private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001620 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001621}
1622
1623testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1624 /* HLR -> SGSN: Cancel Location Request
1625 * HLR <- SGSN: Cancel Location Error
1626 */
1627
1628 var BSSGP_ConnHdlr vc_conn;
1629 f_init();
1630 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001631 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 +02001632 vc_conn.done;
1633}
1634
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001635private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1636 f_TC_attach(id);
1637 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1638}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001639
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001640testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1641 /* MS <-> SGSN: Attach
1642 * MS -> SGSN: Detach Req (Power off)
1643 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1644 */
1645 var BSSGP_ConnHdlr vc_conn;
1646 var integer id := 33;
1647 var charstring imsi := hex2str(f_gen_imsi(id));
1648
1649 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001650 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001651 vc_conn.done;
1652
1653 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1654}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001655
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001656/* Attempt an attach, but loose the Identification Request (IMEI) */
1657private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1658 var integer count_req := 0;
1659 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1660
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001661 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 +02001662
1663 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001664 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001665 /* break */
1666 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001667 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001668 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001669 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001670 repeat;
1671 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001672 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001673 /* ignore ID REQ IMEI */
1674 count_req := count_req + 1;
1675 repeat;
1676 }
1677 }
1678 if (count_req != 5) {
1679 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001680 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001681 }
1682 setverdict(pass);
1683}
1684
1685testcase TC_attach_no_imei_response() runs on test_CT {
1686 /* MS -> SGSN: Attach Request IMSI
1687 * MS <- SGSN: Identity Request IMSI (optional)
1688 * MS -> SGSN: Identity Response IMSI (optional)
1689 * MS <- SGSN: Identity Request IMEI
1690 * MS -x SGSN: no response
1691 * MS <- SGSN: re-send: Identity Request IMEI 4x
1692 * MS <- SGSN: Attach Reject
1693 */
1694 var BSSGP_ConnHdlr vc_conn;
1695 f_init();
1696 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001697 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 +02001698 vc_conn.done;
1699}
1700
Alexander Couzens53f20562018-06-12 16:24:12 +02001701/* Attempt an attach, but loose the Identification Request (IMSI) */
1702private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1703 var integer count_req := 0;
1704 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1705
1706 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1707 g_pars.p_tmsi := 'c0000035'O;
1708
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001709 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 +02001710
1711 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001712 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001713 /* break */
1714 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001715 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001716 /* ignore ID REQ IMSI */
1717 count_req := count_req + 1;
1718 repeat;
1719 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001720 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001721 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001722 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001723 repeat;
1724 }
1725 }
1726 if (count_req != 5) {
1727 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001728 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001729 }
1730 setverdict(pass);
1731}
1732
1733testcase TC_attach_no_imsi_response() runs on test_CT {
1734 /* MS -> SGSN: Attach Request TMSI (unknown)
1735 * MS <- SGSN: Identity Request IMEI (optional)
1736 * MS -> SGSN: Identity Response IMEI (optional)
1737 * MS <- SGSN: Identity Request IMSI
1738 * MS -x SGSN: no response
1739 * MS <- SGSN: re-send: Identity Request IMSI 4x
1740 * MS <- SGSN: Attach Reject
1741 */
1742 var BSSGP_ConnHdlr vc_conn;
1743 f_init();
1744 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001745 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 +02001746 vc_conn.done;
1747}
1748
Alexander Couzenscf818962018-06-05 18:00:00 +02001749private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1750 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1751}
1752
1753testcase TC_attach_check_subscriber_list() runs on test_CT {
1754 /* MS <-> SGSN: Attach
1755 * VTY -> SGSN: Check if MS is in subscriber cache
1756 */
1757 var BSSGP_ConnHdlr vc_conn;
1758 var integer id := 34;
1759 var charstring imsi := hex2str(f_gen_imsi(id));
1760
1761 f_init();
1762 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001763 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001764 vc_conn.done;
1765
1766 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1767 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1768}
1769
Alexander Couzensf9858652018-06-07 16:14:53 +02001770private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1771 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1772 var BssgpDecoded bd;
1773
1774 /* unregister the old IMSI */
1775 f_bssgp_client_unregister(g_pars.imsi);
1776 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001777 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001778 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001779
1780 /* there is no auth */
1781 g_pars.net.expect_auth := false;
1782
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001783 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 +02001784 f_gmm_auth();
1785 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001786 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001787 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001788 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001789 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001790 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001791 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001792 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001793 setverdict(pass);
1794 }
1795 }
1796}
Alexander Couzens03d12242018-08-07 16:13:52 +02001797
1798private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1799
1800 f_TC_attach_closed_foreign(id);
1801 f_TC_attach_closed_imsi_added(id);
1802
1803}
1804
1805
Alexander Couzensf9858652018-06-07 16:14:53 +02001806testcase TC_attach_closed_add_vty() runs on test_CT {
1807 /* VTY-> SGSN: policy close
1808 * MS -> SGSN: Attach Request
1809 * MS <- SGSN: Identity Request IMSI
1810 * MS -> SGSN: Identity Response IMSI
1811 * MS <- SGSN: Attach Reject
1812 * VTY-> SGSN: policy imsi-acl add IMSI
1813 * MS -> SGSN: Attach Request
1814 * MS <- SGSN: Identity Request IMSI
1815 * MS -> SGSN: Identity Response IMSI
1816 * MS <- SGSN: Identity Request IMEI
1817 * MS -> SGSN: Identity Response IMEI
1818 * MS <- SGSN: Attach Accept
1819 */
1820 var BSSGP_ConnHdlr vc_conn;
1821 f_init();
1822 f_sleep(1.0);
1823 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1824 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001825 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1826 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001827 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001828 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001829 vc_conn.done;
1830}
1831
Alexander Couzens0085bd72018-06-12 19:08:44 +02001832/* Attempt an attach, but never answer a Attach Complete */
1833private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1834 var integer count_req := 0;
1835
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001836 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 +02001837 f_gmm_auth();
1838
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001839 timer T := 10.0;
1840 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001841 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001842 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001843 /* break */
1844 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001845 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001846 /* ignore */
1847 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001848 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001849 repeat;
1850 }
1851 }
1852 if (count_req != 5) {
1853 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001854 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001855 }
1856 setverdict(pass);
1857}
1858
1859testcase TC_attach_check_complete_resend() runs on test_CT {
1860 /* MS -> SGSN: Attach Request IMSI
1861 * MS <- SGSN: Identity Request *
1862 * MS -> SGSN: Identity Response *
1863 * MS <- SGSN: Attach Complete 5x
1864 */
1865 var BSSGP_ConnHdlr vc_conn;
1866 f_init();
1867 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001868 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 +02001869 vc_conn.done;
1870}
1871
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001872private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
1873 var BssgpDecoded bd;
1874
1875 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001876 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 +02001877 alt {
1878 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001879 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001880 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001881 setverdict(pass);
1882 }
1883 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
1884 setverdict(fail, "Unexpected RAU Reject");
1885 mtc.stop;
1886 }
1887 [] BSSGP[bssgp].receive { repeat; }
1888 }
1889}
1890
Alexander Couzensbfda9212018-07-31 03:17:33 +02001891private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
1892 var BssgpDecoded bd;
1893
1894 /* first perform regular attach */
1895 f_TC_attach(id);
1896
1897 /* then send RAU */
1898 f_routing_area_update(g_pars.ra);
1899
1900 /* do another RAU */
1901 f_routing_area_update(g_pars.ra);
1902
1903 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1904}
1905
1906testcase TC_attach_rau_a_a() runs on test_CT {
1907 /* MS <-> SGSN: Successful Attach
1908 * MS -> SGSN: Routing Area Update Request
1909 * MS <- SGSN: Routing Area Update Accept
1910 * MS -> SGSN: Routing Area Update Request
1911 * MS <- SGSN: Routing Area Update Accept
1912 * MS -> SGSN: Detach (PowerOff)
1913 */
1914 var BSSGP_ConnHdlr vc_conn;
1915 f_init();
1916 f_sleep(1.0);
1917 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
1918 vc_conn.done;
1919}
1920
Alexander Couzensbe837bd2018-07-31 04:20:11 +02001921private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
1922 var BssgpDecoded bd;
1923
1924 f_TC_attach(id);
1925
1926 log("attach complete sending rau");
1927 f_routing_area_update(g_pars.ra, 0);
1928
1929 log("rau complete unregistering");
1930 f_bssgp_client_unregister(g_pars.imsi);
1931 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
1932
1933 log("sending second RAU via different RA");
1934 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
1935
1936 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
1937}
1938
1939testcase TC_attach_rau_a_b() runs on test_CT {
1940 /* MS <-> SGSN: Successful Attach
1941 * MS -> SGSN: Routing Area _a_ Update Request
1942 * MS <- SGSN: Routing Area _a_ Update Accept
1943 * MS -> SGSN: Routing Area _b_ Update Request
1944 * MS <- SGSN: Routing Area _b_ Update Accept
1945 * MS -> SGSN: Detach (PowerOff)
1946 */
1947 var BSSGP_ConnHdlr vc_conn;
1948 f_init();
1949 f_sleep(1.0);
1950 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
1951 vc_conn.done;
1952}
1953
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02001954private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
1955 var integer count_req := 0;
1956 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1957 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
1958 var BssgpDecoded bd;
1959
1960 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1961
1962 alt {
1963 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1964 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1965 mtc.stop;
1966 }
1967 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1968 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1969 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1970 repeat;
1971 }
1972 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1973 /* send out a second GMM_Attach Request.
1974 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
1975 * of the same content */
1976 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1977 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1978 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1979 }
1980 }
1981 f_sleep(1.0);
1982
1983 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
1984 alt {
1985 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1986 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1987 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1988 repeat;
1989 }
1990 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1991 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
1992 mtc.stop;
1993 }
1994 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1995 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1996 mtc.stop;
1997 }
1998 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
1999 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2000 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2001 setverdict(pass);
2002 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2003 }
2004 }
2005}
2006
2007testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2008 /* Testing if the SGSN ignore Attach Request with the exact same content */
2009 /* MS -> SGSN: Attach Request IMSI
2010 * MS <- SGSN: Identity Request IMSI (optional)
2011 * MS -> SGSN: Identity Response IMSI (optional)
2012 * MS <- SGSN: Identity Request IMEI
2013 * MS -> SGSN: Attach Request (2nd)
2014 * MS <- SGSN: Identity Response IMEI
2015 * MS <- SGSN: Attach Accept
2016 * MS -> SGSN: Attach Complete
2017 */
2018 var BSSGP_ConnHdlr vc_conn;
2019 f_init();
2020 f_sleep(1.0);
2021 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2022 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2023 vc_conn.done;
2024}
2025
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002026private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
2027 var BssgpDecoded bd;
2028 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2029
2030 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2031
2032 /* send Attach Request */
2033 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2034 * 3G auth vectors */
2035 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2036 /* The thing is, if the solSACapability is 'omit', then the
2037 * revisionLevelIndicatior is at the wrong place! */
2038 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2039 f_send_l3_gmm_llc(attach_req);
2040
2041 /* do the auth */
2042 var PDU_L3_MS_SGSN l3_mo;
2043 var PDU_L3_SGSN_MS l3_mt;
2044 var default di := activate(as_mm_identity());
2045
2046 var GSUP_IE auth_tuple;
2047 var template AuthenticationParameterAUTNTLV autn;
2048
2049 g_pars.vec := f_gen_auth_vec_3g();
2050 autn := {
2051 elementIdentifier := '28'O,
2052 lengthIndicator := lengthof(g_pars.vec.autn),
2053 autnValue := g_pars.vec.autn
2054 };
2055 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2056 g_pars.vec.sres,
2057 g_pars.vec.kc,
2058 g_pars.vec.ik,
2059 g_pars.vec.ck,
2060 g_pars.vec.autn,
2061 g_pars.vec.res));
2062 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2063 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2064 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2065
2066 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2067 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2068 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2069
2070 /* send the gmm auth failure with resync IE */
2071 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2072
2073 /* wait for the GSUP resync request */
2074 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2075 g_pars.imsi,
2076 g_pars.vec.auts,
2077 g_pars.vec.rand));
2078
2079 /* generate new key material */
2080 g_pars.vec := f_gen_auth_vec_3g();
2081 autn := {
2082 elementIdentifier := '28'O,
2083 lengthIndicator := lengthof(g_pars.vec.autn),
2084 autnValue := g_pars.vec.autn
2085 };
2086
2087 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2088 g_pars.vec.sres,
2089 g_pars.vec.kc,
2090 g_pars.vec.ik,
2091 g_pars.vec.ck,
2092 g_pars.vec.autn,
2093 g_pars.vec.res));
2094 /* send new key material */
2095 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2096
2097 /* wait for the new Auth Request */
2098 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2099 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2100 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2101 l3_mt := bd.l3_mt;
2102 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2103 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2104 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2105 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2106 valueField := substr(g_pars.vec.res, 0, 4)
2107 };
2108 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2109 elementIdentifier := '21'O,
2110 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2111 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2112 };
2113 l3_mo := valueof(auth_ciph_resp);
2114 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2115 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2116 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2117 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2118 }
2119 f_send_l3_gmm_llc(l3_mo);
2120 deactivate(di);
2121
2122 /* Expect SGSN to perform LU with HLR */
2123 f_gmm_gsup_lu_isd();
2124
2125 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2126 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2127 }
2128 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2129 setverdict(pass);
2130}
2131
2132testcase TC_attach_usim_resync() runs on test_CT {
2133 /* MS -> SGSN: Attach Request
2134 * MS <- SGSN: Identity Request IMSI
2135 * MS -> SGSN: Identity Response IMSI
2136 * MS <- SGSN: Identity Request IMEI
2137 * MS -> SGSN: Identity Response IMEI
2138 * HLR<- SGSN: SAI Request
2139 * HLR-> SGSN: SAI Response
2140 * MS <- SGSN: Auth Request
2141 * MS -> SGSN: Auth Failure (with AUTS)
2142 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2143 * HLR-> SGSN: SAI Response (new key material)
2144 * MS <- SGSN: Auth Request (new key material)
2145 * MS -> SGSN: Auth Response
2146 * MS <- SGSN: Attach Accept
2147 * MS -> SGSN: Attach Complete
2148 */
2149 var BSSGP_ConnHdlr vc_conn;
2150 f_init();
2151 f_sleep(1.0);
2152 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2153 vc_conn.done;
2154}
2155
Harald Welte5ac31492018-02-15 20:39:13 +01002156control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002157 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002158 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002159 execute( TC_attach_umts_aka_umts_res() );
2160 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002161 execute( TC_attach_auth_id_timeout() );
2162 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002163 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002164 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002165 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002166 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002167 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002168 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002169 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002170 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002171 execute( TC_attach_closed_add_vty(), 20.0 );
2172 execute( TC_attach_check_subscriber_list(), 20.0 );
2173 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002174 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002175 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2176 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2177 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2178 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002179 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002180 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002181 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002182 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002183 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002184 execute( TC_detach_unknown_nopoweroff() );
2185 execute( TC_detach_unknown_poweroff() );
2186 execute( TC_detach_nopoweroff() );
2187 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002188 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002189 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002190 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002191 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002192 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002193 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002194 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002195 execute( TC_attach_restart_ctr_echo() );
2196 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002197 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002198 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002199 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Welte5ac31492018-02-15 20:39:13 +01002200}
Harald Welte96a33b02018-02-04 10:36:22 +01002201
2202
2203
2204}