blob: 8b639e65b86536eaac8e8d7696559e9a87beb363 [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 {
140 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
141
142 var RoutingAreaIdentificationV ret := {
143 mccDigit1 := mcc_mnc[0],
144 mccDigit2 := mcc_mnc[1],
145 mccDigit3 := mcc_mnc[2],
146 mncDigit3 := mcc_mnc[5],
147 mncDigit1 := mcc_mnc[3],
148 mncDigit2 := mcc_mnc[4],
149 lac := int2oct(cell_id.ra_id.lai.lac, 16),
150 rac := int2oct(cell_id.ra_id.rac, 8)
151 }
152 return ret;
153};
154
Alexander Couzens51114d12018-07-31 18:41:56 +0200155private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
156 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
157 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100158 /* connect lower end of BSSGP emulation with NS upper port */
159 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
160 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
161 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
162
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200163 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100164 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
165}
166
167private function f_init_gsup(charstring id) runs on test_CT {
168 id := id & "-GSUP";
169 var GsupOps ops := {
170 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
171 };
172
173 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
174 vc_GSUP := GSUP_Emulation_CT.create(id);
175
176 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
177 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
178 /* we use this hack to get events like ASP_IPA_EVENT_UP */
179 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
180
181 vc_GSUP.start(GSUP_Emulation.main(ops, id));
182 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
183
184 /* wait for incoming connection to GSUP port before proceeding */
185 timer T := 10.0;
186 T.start;
187 alt {
188 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
189 [] T.timeout {
190 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200191 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100192 }
193 }
194}
195
Harald Welteeded9ad2018-02-17 20:57:34 +0100196private function f_init_gtp(charstring id) runs on test_CT {
197 id := id & "-GTP";
198
199 var GtpEmulationCfg gtp_cfg := {
200 gtpc_bind_ip := mp_ggsn_ip,
201 gtpc_bind_port := GTP1C_PORT,
202 gtpu_bind_ip := mp_ggsn_ip,
203 gtpu_bind_port := GTP1U_PORT,
204 sgsn_role := false
205 };
206
207 vc_GTP := GTP_Emulation_CT.create(id);
208 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
209}
210
Harald Weltebd194722018-02-16 22:11:08 +0100211private function f_init_vty() runs on test_CT {
212 map(self:SGSNVTY, system:SGSNVTY);
213 f_vty_set_prompts(SGSNVTY);
214 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200215 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100216 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
217}
218
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200219private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
220 if (enable) {
221 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
222 } else {
223 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
224 }
225}
226
Harald Weltebd194722018-02-16 22:11:08 +0100227
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100228function f_init(BcdMccMnc mcc_mnc := '26242F'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100229 if (g_initialized == true) {
230 return;
231 }
232 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100233 g_gb[0].cfg := {
234 nsei := 96,
235 bvci := 196,
236 cell_id := {
237 ra_id := {
238 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100239 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100240 rac := 0
241 },
242 cell_id := 20960
243 },
244 sgsn_role := false
245 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200246 g_gb[1].cfg := {
247 nsei := 97,
248 bvci := 210,
249 cell_id := {
250 ra_id := {
251 lai := {
252 mcc_mnc := mcc_mnc, lac := 13200},
253 rac := 0
254 },
255 cell_id := 20961
256 },
257 sgsn_role := false
258 };
259 g_gb[2].cfg := {
260 nsei := 98,
261 bvci := 220,
262 cell_id := {
263 ra_id := {
264 lai := {
265 mcc_mnc := mcc_mnc, lac := 13300},
266 rac := 0
267 },
268 cell_id := 20962
269 },
270 sgsn_role := false
271 };
Harald Welte96a33b02018-02-04 10:36:22 +0100272
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200273 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200274 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
275 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
276 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte5ac31492018-02-15 20:39:13 +0100277 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100278 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200279 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100280}
Harald Welte96a33b02018-02-04 10:36:22 +0100281
Harald Welte5ac31492018-02-15 20:39:13 +0100282type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
283
284/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200285function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100286 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100287runs on test_CT return BSSGP_ConnHdlr {
288 var BSSGP_ConnHdlr vc_conn;
289 var SGSN_ConnHdlrNetworkPars net_pars := {
290 expect_ptmsi := true,
291 expect_auth := true,
292 expect_ciph := false
293 };
294 var BSSGP_ConnHdlrPars pars := {
295 imei := f_gen_imei(imsi_suffix),
296 imsi := f_gen_imsi(imsi_suffix),
297 msisdn := f_gen_msisdn(imsi_suffix),
298 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100299 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100300 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100301 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100302 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200303 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 +0100304 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100305 net := net_pars,
306 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100307 };
308
309 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200310 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
311 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
312 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
313 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
314 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
315 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100316
317 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
318 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
319
Harald Welteeded9ad2018-02-17 20:57:34 +0100320 connect(vc_conn:GTP, vc_GTP:CLIENT);
321 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
322
Harald Welte5ac31492018-02-15 20:39:13 +0100323 vc_conn.start(f_handler_init(fn, id, pars));
324 return vc_conn;
325}
326
Harald Welte62e29582018-02-16 21:17:11 +0100327private altstep as_Tguard() runs on BSSGP_ConnHdlr {
328 [] g_Tguard.timeout {
329 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200330 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100331 }
332}
333
Harald Welte5ac31492018-02-15 20:39:13 +0100334/* first function called in every ConnHdlr */
335private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
336runs on BSSGP_ConnHdlr {
337 /* do some common stuff like setting up g_pars */
338 g_pars := pars;
339
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200340 llc := f_llc_create(false);
341
Harald Welte5ac31492018-02-15 20:39:13 +0100342 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200343 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100344 /* tell GSUP dispatcher to send this IMSI to us */
345 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100346 /* tell GTP dispatcher to send this IMSI to us */
347 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100348
Harald Welte62e29582018-02-16 21:17:11 +0100349 g_Tguard.start(pars.t_guard);
350 activate(as_Tguard());
351
Harald Welte5ac31492018-02-15 20:39:13 +0100352 /* call the user-supplied test case function */
353 fn.apply(id);
354 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100355}
356
357/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100358 * Detach without Attach
359 * SM procedures without attach / RAU
360 * ATTACH / RAU
361 ** with / without authentication
362 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100363 * re-transmissions of LLC frames
364 * PDP Context activation
365 ** with different GGSN config in SGSN VTY
366 ** with different PDP context type (v4/v6/v46)
367 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100368 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100369 */
370
371testcase TC_wait_ns_up() runs on test_CT {
372 f_init();
373 f_sleep(20.0);
374}
375
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200376function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
377 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
378 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
379 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
380 var octetstring llc_enc := enc_PDU_LLC(valueof(ts_LLC_UI(l3_enc, sapi, '0'B, n_u)));
381 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
382}
383
Harald Welte5ac31492018-02-15 20:39:13 +0100384altstep as_mm_identity() runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100385 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200386 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100387 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200388 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100389 repeat;
390 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200391 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100392 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200393 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100394 repeat;
395 }
396}
Harald Welte96a33b02018-02-04 10:36:22 +0100397
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200398/* perform GMM authentication (if expected).
399 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
400 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
401function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100402 var BssgpDecoded bd;
403 var PDU_L3_MS_SGSN l3_mo;
404 var PDU_L3_SGSN_MS l3_mt;
405 var default di := activate(as_mm_identity());
406 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200407 var GSUP_IE auth_tuple;
408 var template AuthenticationParameterAUTNTLV autn;
409
410 if (umts_aka_challenge) {
411 g_pars.vec := f_gen_auth_vec_3g();
412 autn := {
413 elementIdentifier := '28'O,
414 lengthIndicator := lengthof(g_pars.vec.autn),
415 autnValue := g_pars.vec.autn
416 };
417
418 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
419 g_pars.vec.sres,
420 g_pars.vec.kc,
421 g_pars.vec.ik,
422 g_pars.vec.ck,
423 g_pars.vec.autn,
424 g_pars.vec.res));
425 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
426 } else {
427 g_pars.vec := f_gen_auth_vec_2g();
428 autn := omit;
429 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
430 g_pars.vec.sres,
431 g_pars.vec.kc));
432 log("GSUP sends only 2G auth tuple", auth_tuple);
433 }
Harald Welte5ac31492018-02-15 20:39:13 +0100434 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
435 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200436
437 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
438 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200439 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
Harald Welte5ac31492018-02-15 20:39:13 +0100440 l3_mt := bd.l3_mt;
441 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200442 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
443
444 if (umts_aka_challenge and not force_gsm_sres) {
445 /* set UMTS response instead */
446 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
447 valueField := substr(g_pars.vec.res, 0, 4)
448 };
449 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
450 elementIdentifier := '21'O,
451 lengthIndicator := lengthof(g_pars.vec.res) - 4,
452 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
453 };
454 }
455
456 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100457 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
458 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
459 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
460 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
461 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200462 f_send_l3_gmm_llc(l3_mo);
Harald Welte76dee092018-02-16 22:12:59 +0100463 } else {
464 /* wait for identity procedure */
465 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100466 }
Harald Welte76dee092018-02-16 22:12:59 +0100467
Harald Welte5ac31492018-02-15 20:39:13 +0100468 deactivate(di);
469}
470
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200471function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100472 g_pars.p_tmsi := p_tmsi;
473 /* update TLLI */
474 g_pars.tlli_old := g_pars.tlli;
475 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200476 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100477}
478
Harald Welte04683d02018-02-16 22:43:45 +0100479function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
480 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100481 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200482 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100483 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200484 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200485 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100486 }
Harald Welte04683d02018-02-16 22:43:45 +0100487 g_pars.ra := aa.routingAreaIdentification;
488 if (ispresent(aa.allocatedPTMSI)) {
489 if (not g_pars.net.expect_ptmsi) {
490 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200491 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100492 }
Harald Weltef70997d2018-02-17 10:11:19 +0100493 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100494 }
495 if (ispresent(aa.msIdentity)) {
496 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200497 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100498 }
499 /* P-TMSI.sig */
500 if (ispresent(aa.ptmsiSignature)) {
501 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
502 }
503 /* updateTimer */
504 // aa.readyTimer
505 /* T3302, T3319, T3323, T3312_ext, T3324 */
506}
507
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200508function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100509 /* mandatory IE */
510 g_pars.ra := ra.routingAreaId;
511 if (ispresent(ra.allocatedPTMSI)) {
512 if (not g_pars.net.expect_ptmsi) {
513 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200514 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100515 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200516 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100517 }
518 if (ispresent(ra.msIdentity)) {
519 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200520 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100521 }
522 /* P-TMSI.sig */
523 if (ispresent(ra.ptmsiSignature)) {
524 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
525 }
526 /* updateTimer */
527 // aa.readyTimer
528 /* T3302, T3319, T3323, T3312_ext, T3324 */
529}
530
531
Harald Welte5a4fa042018-02-16 20:59:21 +0100532function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
533 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
534}
535
Harald Welte23178c52018-02-17 09:36:33 +0100536/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100537private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100538 if (ispresent(g_pars.p_tmsi)) {
539 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
540 } else {
541 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
542 }
543}
544
Harald Welte311ec272018-02-17 09:40:03 +0100545private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100546 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100547 /* Expect MSC to perform LU with HLR */
548 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100549 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
550 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
551 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100552 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
553 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
554}
555
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200556private function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100557 var BssgpDecoded bd;
Harald Welte5a4fa042018-02-16 20:59:21 +0100558 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200559 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 +0100560
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200561 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
562 * 3G auth vectors */
563 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
564 /* The thing is, if the solSACapability is 'omit', then the
565 * revisionLevelIndicatior is at the wrong place! */
566 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
567
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200568 f_send_l3_gmm_llc(attach_req);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200569 f_gmm_auth(umts_aka_challenge, force_gsm_sres);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200570 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100571 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100572
Alexander Couzens0e510e62018-07-28 23:06:00 +0200573 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100574 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
575 }
576 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200577 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200578}
579
580private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
581 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100582 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100583}
584
585testcase TC_attach() runs on test_CT {
586 var BSSGP_ConnHdlr vc_conn;
587 f_init();
588 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200589 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100590 vc_conn.done;
591}
592
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100593testcase TC_attach_mnc3() runs on test_CT {
594 var BSSGP_ConnHdlr vc_conn;
595 f_init('023042'H);
596 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200597 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100598 vc_conn.done;
599}
600
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200601private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
602 f_gmm_attach(true, false);
603 setverdict(pass);
604}
605testcase TC_attach_umts_aka_umts_res() runs on test_CT {
606 var BSSGP_ConnHdlr vc_conn;
607 f_init();
608 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200609 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200610 vc_conn.done;
611}
612
613private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
614 f_gmm_attach(true, true);
615 setverdict(pass);
616}
617testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
618 var BSSGP_ConnHdlr vc_conn;
619 f_init();
620 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200621 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200622 vc_conn.done;
623}
624
Harald Welte5b7c8122018-02-16 21:48:17 +0100625/* MS never responds to ID REQ, expect ATTACH REJECT */
626private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100627 var RoutingAreaIdentificationV old_ra := f_random_RAI();
628
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200629 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 +0100630 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200631 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100632 /* don't send ID Response */
633 repeat;
634 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200635 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100636 setverdict(pass);
637 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200638 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100639 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200640 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100641 }
642 }
643}
644testcase TC_attach_auth_id_timeout() runs on test_CT {
645 var BSSGP_ConnHdlr vc_conn;
646 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200647 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 +0100648 vc_conn.done;
649}
650
651/* HLR never responds to SAI REQ, expect ATTACH REJECT */
652private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100653 var RoutingAreaIdentificationV old_ra := f_random_RAI();
654
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200655 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 +0100656 alt {
657 [] as_mm_identity();
658 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
659 }
660 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200661 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100662 setverdict(pass);
663}
664testcase TC_attach_auth_sai_timeout() runs on test_CT {
665 var BSSGP_ConnHdlr vc_conn;
666 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200667 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100668 vc_conn.done;
669}
670
Harald Weltefe253882018-02-17 09:25:00 +0100671/* HLR rejects SAI, expect ATTACH REJECT */
672private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100673 var RoutingAreaIdentificationV old_ra := f_random_RAI();
674
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200675 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 +0100676 alt {
677 [] as_mm_identity();
678 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
679 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
680 }
681 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200682 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100683 setverdict(pass);
684}
685testcase TC_attach_auth_sai_reject() runs on test_CT {
686 var BSSGP_ConnHdlr vc_conn;
687 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200688 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100689 vc_conn.done;
690}
691
Harald Welte5b7c8122018-02-16 21:48:17 +0100692/* HLR never responds to UL REQ, expect ATTACH REJECT */
693private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100694 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100695 var RoutingAreaIdentificationV old_ra := f_random_RAI();
696
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200697 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 +0100698 f_gmm_auth();
699 /* Expect MSC to perform LU with HLR */
700 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
701 /* Never follow-up with ISD_REQ or UL_RES */
702 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200703 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100704 setverdict(pass);
705 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200706 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100707 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100708 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200709 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100710 }
711 }
712}
713testcase TC_attach_gsup_lu_timeout() runs on test_CT {
714 var BSSGP_ConnHdlr vc_conn;
715 f_init();
716 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200717 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100718 vc_conn.done;
719}
720
Harald Welteb7c14e92018-02-17 09:29:16 +0100721/* HLR rejects UL REQ, expect ATTACH REJECT */
722private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
723 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100724 var RoutingAreaIdentificationV old_ra := f_random_RAI();
725
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200726 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 +0100727 f_gmm_auth();
728 /* Expect MSC to perform LU with HLR */
729 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
730 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
731 }
732 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200733 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100734 setverdict(pass);
735 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200736 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100737 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
738 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200739 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100740 }
741 }
742}
743testcase TC_attach_gsup_lu_reject() runs on test_CT {
744 var BSSGP_ConnHdlr vc_conn;
745 f_init();
746 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200747 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100748 vc_conn.done;
749}
750
751
Harald Welte3823e2e2018-02-16 21:53:48 +0100752/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
753private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100754 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100755 var RoutingAreaIdentificationV old_ra := f_random_RAI();
756
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200757 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 +0100758 f_gmm_auth();
759 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100760 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100761
Alexander Couzens0e510e62018-07-28 23:06:00 +0200762 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100763 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
764 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200765 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100766 setverdict(pass);
767}
Harald Welte3823e2e2018-02-16 21:53:48 +0100768testcase TC_attach_combined() runs on test_CT {
769 var BSSGP_ConnHdlr vc_conn;
770 f_init();
771 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200772 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100773 vc_conn.done;
774}
775
Harald Welte76dee092018-02-16 22:12:59 +0100776/* Attempt of GPRS ATTACH in 'accept all' mode */
777private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100778 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100779 var RoutingAreaIdentificationV old_ra := f_random_RAI();
780
781 g_pars.net.expect_auth := false;
782
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200783 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 +0100784 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200785 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100786 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
787 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200788 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100789 setverdict(pass);
790}
791testcase TC_attach_accept_all() runs on test_CT {
792 var BSSGP_ConnHdlr vc_conn;
793 f_init();
794 f_sleep(1.0);
795 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200796 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100797 vc_conn.done;
798}
Harald Welte5b7c8122018-02-16 21:48:17 +0100799
Harald Welteb2124b22018-02-16 22:26:56 +0100800/* Attempt of GPRS ATTACH in 'accept all' mode */
801private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100802 var RoutingAreaIdentificationV old_ra := f_random_RAI();
803
804 /* Simulate a foreign IMSI */
805 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200806 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100807
808 g_pars.net.expect_auth := false;
809
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200810 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100811 alt {
812 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200813 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100814 setverdict(pass);
815 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200816 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100817 setverdict(pass);
818 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200819 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200820 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200821 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200822 }
Harald Welteb2124b22018-02-16 22:26:56 +0100823 }
824}
825testcase TC_attach_closed() runs on test_CT {
826 var BSSGP_ConnHdlr vc_conn;
827 f_init();
828 f_sleep(1.0);
829 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
830 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200831 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100832 vc_conn.done;
833 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200834 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100835 vc_conn.done;
836}
837
Harald Welte04683d02018-02-16 22:43:45 +0100838/* Routing Area Update from Unknown TLLI -> REJECT */
839private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100840 var RoutingAreaIdentificationV old_ra := f_random_RAI();
841
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200842 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 +0100843 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200844 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100845 setverdict(pass);
846 }
847 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200848 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100849 }
850}
851testcase TC_rau_unknown() runs on test_CT {
852 var BSSGP_ConnHdlr vc_conn;
853 f_init();
854 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200855 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100856 vc_conn.done;
857}
858
Harald Welte91636de2018-02-17 10:16:14 +0100859private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
860 var BssgpDecoded bd;
861
862 /* first perform regular attach */
863 f_TC_attach(id);
864
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200865 f_routing_area_update(g_pars.ra);
866
Harald Welte91636de2018-02-17 10:16:14 +0100867}
868testcase TC_attach_rau() runs on test_CT {
869 var BSSGP_ConnHdlr vc_conn;
870 f_init();
871 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200872 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100873 vc_conn.done;
874}
Harald Welte04683d02018-02-16 22:43:45 +0100875
Harald Welte6abb9fe2018-02-17 15:24:48 +0100876/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200877function 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 +0100878 var BssgpDecoded bd;
879 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200880 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100881 if (expect_purge) {
882 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
883 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
884 }
885 T.start;
886 alt {
887 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
888 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200889 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100890 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200891 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100892 g_pars.ra := omit;
893 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200894 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100895 /* TODO: check if any PDP contexts are deactivated on network side? */
896 }
897 [power_off] T.timeout {
898 setverdict(pass);
899 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200900 [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 +0100901 g_pars.ra := omit;
902 setverdict(pass);
903 /* TODO: check if any PDP contexts are deactivated on network side? */
904 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200905 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100906 }
907}
908
909/* IMSI DETACH (non-power-off) for unknown TLLI */
910private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
911 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
912}
913testcase TC_detach_unknown_nopoweroff() runs on test_CT {
914 var BSSGP_ConnHdlr vc_conn;
915 f_init();
916 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200917 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100918 vc_conn.done;
919}
920
921/* IMSI DETACH (power-off) for unknown TLLI */
922private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
923 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
924}
925testcase TC_detach_unknown_poweroff() runs on test_CT {
926 var BSSGP_ConnHdlr vc_conn;
927 f_init();
928 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200929 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100930 vc_conn.done;
931}
932
933/* IMSI DETACH (non-power-off) for known TLLI */
934private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
935 /* first perform regular attach */
936 f_TC_attach(id);
937
938 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
939}
940testcase TC_detach_nopoweroff() runs on test_CT {
941 var BSSGP_ConnHdlr vc_conn;
942 f_init();
943 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200944 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100945 vc_conn.done;
946}
947
948/* IMSI DETACH (power-off) for known TLLI */
949private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
950 /* first perform regular attach */
951 f_TC_attach(id);
952
953 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
954}
955testcase TC_detach_poweroff() runs on test_CT {
956 var BSSGP_ConnHdlr vc_conn;
957 f_init();
958 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200959 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100960 vc_conn.done;
961}
962
Harald Welteeded9ad2018-02-17 20:57:34 +0100963type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100964 BIT3 tid, /* L3 Transaction ID */
965 BIT4 nsapi, /* SNDCP NSAPI */
966 BIT4 sapi, /* LLC SAPI */
967 QoSV qos, /* QoS parameters */
968 PDPAddressV addr, /* IP address */
969 octetstring apn optional, /* APN name */
970 ProtocolConfigOptionsV pco optional, /* protoco config opts */
971 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100972 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100973 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100974
Harald Welte822f9102018-02-18 20:39:06 +0100975 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
976 OCT4 ggsn_tei_u, /* GGSN TEI User */
977 octetstring ggsn_ip_c, /* GGSN IP Control */
978 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200979 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100980
Harald Welte822f9102018-02-18 20:39:06 +0100981 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
982 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
983 octetstring sgsn_ip_c optional, /* SGSN IP Control */
984 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100985};
986
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100987
988private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
989 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
990 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
991 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
992 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
993 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
994 f_gtp_register_teid(apars.ggsn_tei_c);
995 f_gtp_register_teid(apars.ggsn_tei_u);
996}
997
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200998function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100999 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1000 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001001 var template Recovery_gtpc recovery := omit;
1002
1003 if (send_recovery) {
1004 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1005 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001006
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001007 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 +01001008 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001009 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1010 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1011 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1012 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1013 apars.sgsn_tei_c, apars.gtp_resp_cause,
1014 apars.ggsn_tei_c, apars.ggsn_tei_u,
1015 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001016 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1017 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001018 }
1019 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001020 [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 +01001021 setverdict(pass);
1022 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001023 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001024 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001025 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001026 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001027 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001028 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001029 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001030 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001031 [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 +01001032 setverdict(pass);
1033 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001034 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +01001035 }
1036}
1037
Harald Welte6f203162018-02-18 22:04:55 +01001038function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
1039 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1040 var Gtp1cUnitdata g_ud;
1041
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001042 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
Harald Welte6f203162018-02-18 22:04:55 +01001043 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1044 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001045 BSSGP[0].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001046 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1047 }
1048 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001049 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001050 setverdict(pass);
1051 }
1052 [] as_xid(apars);
1053 }
1054}
1055
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001056function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001057 var Gtp1cUnitdata g_ud;
1058 var integer seq_nr := 23;
1059 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1060
Alexander Couzens0e510e62018-07-28 23:06:00 +02001061 BSSGP[0].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001062 if (error_ind) {
1063 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1064 } else {
1065 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1066 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001067
1068 timer T := 5.0;
1069 T.start;
1070
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001071 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001072 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001073 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Harald Welte57b9b7f2018-02-18 22:28:13 +01001074 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001075 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1076 repeat;
1077 }
1078 [] T.timeout {
1079 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1080 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001081 }
1082}
1083
Harald Welte6f203162018-02-18 22:04:55 +01001084
Harald Welteeded9ad2018-02-17 20:57:34 +01001085/* Table 10.5.156/3GPP TS 24.008 */
1086template (value) QoSV t_QosDefault := {
1087 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1088 delayClass := '100'B, /* best effort */
1089 spare1 := '00'B,
1090 precedenceClass := '010'B, /* normal */
1091 spare2 := '0'B,
1092 peakThroughput := '0000'B, /* subscribed */
1093 meanThroughput := '00000'B, /* subscribed */
1094 spare3 := '000'B,
1095 deliverErroneusSDU := omit,
1096 deliveryOrder := omit,
1097 trafficClass := omit,
1098 maxSDUSize := omit,
1099 maxBitrateUplink := omit,
1100 maxBitrateDownlink := omit,
1101 sduErrorRatio := omit,
1102 residualBER := omit,
1103 trafficHandlingPriority := omit,
1104 transferDelay := omit,
1105 guaranteedBitRateUplink := omit,
1106 guaranteedBitRateDownlink := omit,
1107 sourceStatisticsDescriptor := omit,
1108 signallingIndication := omit,
1109 spare4 := omit,
1110 maxBitrateDownlinkExt := omit,
1111 guaranteedBitRateDownlinkExt := omit,
1112 maxBitrateUplinkExt := omit,
1113 guaranteedBitRateUplinkExt := omit,
1114 maxBitrateDownlinkExt2 := omit,
1115 guaranteedBitRateDownlinkExt2 := omit,
1116 maxBitrateUplinkExt2 := omit,
1117 guaranteedBitRateUplinkExt2 := omit
1118}
1119
1120/* 10.5.6.4 / 3GPP TS 24.008 */
1121template (value) PDPAddressV t_AddrIPv4dyn := {
1122 pdpTypeOrg := '0001'B, /* IETF */
1123 spare := '0000'B,
1124 pdpTypeNum := '21'O, /* IPv4 */
1125 addressInfo := omit
1126}
1127template (value) PDPAddressV t_AddrIPv6dyn := {
1128 pdpTypeOrg := '0001'B, /* IETF */
1129 spare := '0000'B,
1130 pdpTypeNum := '53'O, /* IPv6 */
1131 addressInfo := omit
1132}
1133
Harald Welte37692d82018-02-18 15:21:34 +01001134template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001135 tid := '000'B,
1136 nsapi := '0101'B, /* < 5 are reserved */
1137 sapi := '0011'B, /* 3/5/9/11 */
1138 qos := t_QosDefault,
1139 addr := t_AddrIPv4dyn,
1140 apn := omit,
1141 pco := omit,
1142 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001143 gtp_resp_cause := int2oct(128, 1),
1144 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001145
1146 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001147 ggsn_tei_c := f_rnd_octstring(4),
1148 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001149 ggsn_ip_c := f_inet_addr(ggsn_ip),
1150 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001151 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001152
Harald Welteeded9ad2018-02-17 20:57:34 +01001153 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001154 sgsn_tei_u := omit,
1155 sgsn_ip_c := omit,
1156 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001157}
1158
Harald Welte37692d82018-02-18 15:21:34 +01001159template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1160 connId := 1,
1161 remName := f_inet_ntoa(ip),
1162 remPort := GTP1U_PORT
1163}
1164
1165template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1166 connId := 1,
1167 remName := f_inet_ntoa(ip),
1168 remPort := GTP1C_PORT
1169}
1170
1171private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1172 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1173 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1174}
1175
1176private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001177 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001178 repeat;
1179 }
1180}
1181
1182template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1183 pDU_SN_UNITDATA := {
1184 nsapi := nsapi,
1185 moreBit := ?,
1186 snPduType := '1'B,
1187 firstSegmentIndicator := ?,
1188 spareBit := ?,
1189 pcomp := ?,
1190 dcomp := ?,
1191 npduNumber := ?,
1192 segmentNumber := ?,
1193 npduNumberContinued := ?,
1194 dataSegmentSnUnitdataPdu := payload
1195 }
1196}
1197
1198/* simple case: single segment, no compression */
1199template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1200 pDU_SN_UNITDATA := {
1201 nsapi := nsapi,
1202 moreBit := '0'B,
1203 snPduType := '1'B,
1204 firstSegmentIndicator := '1'B,
1205 spareBit := '0'B,
1206 pcomp := '0000'B,
1207 dcomp := '0000'B,
1208 npduNumber := '0000'B,
1209 segmentNumber := '0000'B,
1210 npduNumberContinued := '00'O,
1211 dataSegmentSnUnitdataPdu := payload
1212 }
1213}
1214
1215/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1216private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1217 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1218 f_gtpu_send(apars, payload);
1219 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1220 alt {
1221 [] as_xid(apars);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001222 [] BSSGP[0].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001223 }
1224}
1225
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001226/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001227private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1228 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1229 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1230 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001231 BSSGP[0].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001232 /* Expect PDU via GTP from SGSN on simulated GGSN */
1233 alt {
1234 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1235 }
1236}
1237
Harald Welteeded9ad2018-02-17 20:57:34 +01001238private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001239 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001240
1241 /* first perform regular attach */
1242 f_TC_attach(id);
1243
1244 f_pdp_ctx_act(apars);
1245}
1246testcase TC_attach_pdp_act() runs on test_CT {
1247 var BSSGP_ConnHdlr vc_conn;
1248 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001249 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001250 vc_conn.done;
1251}
Harald Welteb2124b22018-02-16 22:26:56 +01001252
Harald Welte835b15f2018-02-18 14:39:11 +01001253/* PDP Context activation for not-attached subscriber; expect fail */
1254private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001255 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001256 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 +01001257 apars.apn, apars.pco));
1258 alt {
1259 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001260 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001261 setverdict(pass);
1262 }
1263 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1264 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001265 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001266 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001267 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001268 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001269 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001270 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001271 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001272 }
1273}
1274testcase TC_pdp_act_unattached() runs on test_CT {
1275 var BSSGP_ConnHdlr vc_conn;
1276 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001277 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001278 vc_conn.done;
1279}
1280
Harald Welte37692d82018-02-18 15:21:34 +01001281/* ATTACH + PDP CTX ACT + user plane traffic */
1282private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1283 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1284
1285 /* first perform regular attach */
1286 f_TC_attach(id);
1287 /* then activate PDP context */
1288 f_pdp_ctx_act(apars);
1289 /* then transceive a downlink PDU */
1290 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1291 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1292}
1293testcase TC_attach_pdp_act_user() runs on test_CT {
1294 var BSSGP_ConnHdlr vc_conn;
1295 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001296 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001297 vc_conn.done;
1298}
1299
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001300/* ATTACH + PDP CTX ACT; reject from GGSN */
1301private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1302 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1303
1304 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1305 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1306
1307 /* first perform regular attach */
1308 f_TC_attach(id);
1309 /* then activate PDP context */
1310 f_pdp_ctx_act(apars);
1311}
1312testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1313 var BSSGP_ConnHdlr vc_conn;
1314 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001315 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001316 vc_conn.done;
1317}
Harald Welte835b15f2018-02-18 14:39:11 +01001318
Harald Welte6f203162018-02-18 22:04:55 +01001319/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1320private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1321 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1322
1323 /* first perform regular attach */
1324 f_TC_attach(id);
1325 /* then activate PDP context */
1326 f_pdp_ctx_act(apars);
1327 /* then transceive a downlink PDU */
1328 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1329 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1330
1331 f_pdp_ctx_deact_mo(apars, '00'O);
1332}
1333testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1334 var BSSGP_ConnHdlr vc_conn;
1335 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001336 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 +01001337 vc_conn.done;
1338}
1339
Harald Welte57b9b7f2018-02-18 22:28:13 +01001340/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1341private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1342 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1343
1344 /* first perform regular attach */
1345 f_TC_attach(id);
1346 /* then activate PDP context */
1347 f_pdp_ctx_act(apars);
1348 /* then transceive a downlink PDU */
1349 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1350 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1351
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001352 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001353}
1354testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1355 var BSSGP_ConnHdlr vc_conn;
1356 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001357 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 +01001358 vc_conn.done;
1359}
1360
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001361/* ATTACH + ATTACH (2nd) */
1362private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1363 g_pars.t_guard := 5.0;
1364
1365 /* first perform regular attach */
1366 f_TC_attach(id);
1367
1368 /* second to perform regular attach */
1369 f_TC_attach(id);
1370}
1371
1372
1373testcase TC_attach_second_attempt() runs on test_CT {
1374 var BSSGP_ConnHdlr vc_conn;
1375 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001376 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001377 vc_conn.done;
1378}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001379
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001380private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001381 var Gtp1cUnitdata g_ud;
1382 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1383
1384 /* first perform regular attach */
1385 f_TC_attach(id);
1386 /* Activate a pdp context against the GGSN */
1387 f_pdp_ctx_act(apars);
1388 /* Wait to receive first echo request and send initial Restart counter */
1389 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1390 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1391 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1392 }
1393 /* Wait to receive second echo request and send incremented Restart
1394 counter. This will fake a restarted GGSN, and pdp ctx allocated
1395 should be released by SGSN */
1396 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1397 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1398 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1399 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1400 }
1401 var OCT1 cause_network_failure := int2oct(38, 1)
1402 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001403 [] 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 +02001404 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001405 setverdict(pass);
1406 }
1407 [] as_xid(apars);
1408 }
1409 setverdict(pass);
1410}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001411/* ATTACH + trigger Recovery procedure through EchoResp */
1412testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001413 var BSSGP_ConnHdlr vc_conn;
1414 g_use_echo := true
1415 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001416 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 +02001417 vc_conn.done;
1418 g_use_echo := false
1419}
1420
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001421private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1422 var Gtp1cUnitdata g_ud;
1423 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1424 var integer seq_nr := 23;
1425 var GtpPeer peer;
1426 /* first perform regular attach */
1427 f_TC_attach(id);
1428
1429 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1430 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1431 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1432 f_pdp_ctx_act(apars, true);
1433
1434 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1435/* received. */
1436 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1437
1438 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1439 would be great to have an active pdp context here before triggering
1440 Recovery, and making sure the the DEACT request is sent by the SGSN.
1441 */
1442
1443 /* Activate a pdp context against the GGSN, send incremented Recovery
1444 IE. This should trigger the recovery path, but still this specific
1445 CTX activation should work. */
1446 apars.exp_rej_cause := omit; /* default value for tests */
1447 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1448 f_pdp_ctx_act(apars, true);
1449
1450 setverdict(pass);
1451}
1452/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1453testcase TC_attach_restart_ctr_create() runs on test_CT {
1454 var BSSGP_ConnHdlr vc_conn;
1455 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001456 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 +02001457 vc_conn.done;
1458}
1459
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001460/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1461private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1462 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1463 var integer seq_nr := 23;
1464 var GtpPeer peer;
1465 var integer i;
1466
1467 /* first perform regular attach */
1468 f_TC_attach(id);
1469 /* then activate PDP context */
1470 f_pdp_ctx_act(apars);
1471
Alexander Couzens0e510e62018-07-28 23:06:00 +02001472 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001473 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1474 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1475
1476 for (i := 0; i < 5; i := i+1) {
1477 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001478 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001479 [] as_xid(apars);
1480 }
1481 }
1482
1483 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1484
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001485 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001486 setverdict(pass);
1487}
1488testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1489 var BSSGP_ConnHdlr vc_conn;
1490 f_init();
1491 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001492 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 +02001493 vc_conn.done;
1494}
1495
Alexander Couzens5e307b42018-05-22 18:12:20 +02001496private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1497 /* MS: perform regular attach */
1498 f_TC_attach(id);
1499
1500 /* HLR: cancel the location request */
1501 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1502 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001503
1504 /* ensure no Detach Request got received */
1505 timer T := 5.0;
1506 T.start;
1507 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001508 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001509 T.stop;
1510 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001511 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001512 }
1513 [] T.timeout {
1514 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001515 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001516 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001517 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001518 repeat;
1519 }
1520 }
1521}
1522
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001523/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1524private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1525 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1526
1527 /* first perform regular attach */
1528 f_TC_attach(id);
1529 /* then activate PDP context */
1530 f_pdp_ctx_act(apars);
1531 /* then transceive a downlink PDU */
1532 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1533
1534 /* Send Error indication as response from upload PDU and expect deact towards MS */
1535 f_pdp_ctx_deact_mt(apars, true);
1536}
1537testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1538 var BSSGP_ConnHdlr vc_conn;
1539 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001540 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 +02001541 vc_conn.done;
1542}
1543
Alexander Couzens5e307b42018-05-22 18:12:20 +02001544testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1545 /* MS <-> SGSN: GMM Attach
1546 * HLR -> SGSN: Cancel Location Request
1547 * HLR <- SGSN: Cancel Location Ack
1548 */
1549 var BSSGP_ConnHdlr vc_conn;
1550 f_init();
1551 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001552 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001553 vc_conn.done;
1554}
1555
1556
Alexander Couzensc87967a2018-05-22 16:09:54 +02001557private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1558 /* MS: perform regular attach */
1559 f_TC_attach(id);
1560
1561 /* HLR: cancel the location request */
1562 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1563 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1564 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1565
1566 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001567 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 +02001568 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001569
1570 setverdict(pass);
1571}
1572
1573testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1574 /* MS <-> SGSN: GMM Attach
1575 * HLR -> SGSN: Cancel Location Request
1576 * HLR <- SGSN: Cancel Location Ack
1577 * MS <- SGSN: Detach Request
1578 * SGSN-> MS: Detach Complete
1579 */
1580 var BSSGP_ConnHdlr vc_conn;
1581 f_init();
1582 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001583 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001584 vc_conn.done;
1585}
1586
1587
Alexander Couzens6c47f292018-05-22 17:09:49 +02001588private function f_hlr_location_cancel_request_unknown_subscriber(
1589 charstring id,
1590 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1591
1592 /* HLR: cancel the location request */
1593 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1594
1595 /* cause 2 = IMSI_UNKNOWN */
1596 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1597
1598 setverdict(pass);
1599}
1600
1601private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001602 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001603}
1604
1605testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1606 /* HLR -> SGSN: Cancel Location Request
1607 * HLR <- SGSN: Cancel Location Error
1608 */
1609
1610 var BSSGP_ConnHdlr vc_conn;
1611 f_init();
1612 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001613 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 +02001614 vc_conn.done;
1615}
1616
1617private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001618 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001619}
1620
1621testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1622 /* HLR -> SGSN: Cancel Location Request
1623 * HLR <- SGSN: Cancel Location Error
1624 */
1625
1626 var BSSGP_ConnHdlr vc_conn;
1627 f_init();
1628 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001629 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 +02001630 vc_conn.done;
1631}
1632
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001633private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1634 f_TC_attach(id);
1635 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1636}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001637
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001638testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1639 /* MS <-> SGSN: Attach
1640 * MS -> SGSN: Detach Req (Power off)
1641 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1642 */
1643 var BSSGP_ConnHdlr vc_conn;
1644 var integer id := 33;
1645 var charstring imsi := hex2str(f_gen_imsi(id));
1646
1647 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001648 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001649 vc_conn.done;
1650
1651 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1652}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001653
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001654/* Attempt an attach, but loose the Identification Request (IMEI) */
1655private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1656 var integer count_req := 0;
1657 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1658
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001659 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 +02001660
1661 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001662 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001663 /* break */
1664 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001665 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001666 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001667 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001668 repeat;
1669 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001670 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001671 /* ignore ID REQ IMEI */
1672 count_req := count_req + 1;
1673 repeat;
1674 }
1675 }
1676 if (count_req != 5) {
1677 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001678 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001679 }
1680 setverdict(pass);
1681}
1682
1683testcase TC_attach_no_imei_response() runs on test_CT {
1684 /* MS -> SGSN: Attach Request IMSI
1685 * MS <- SGSN: Identity Request IMSI (optional)
1686 * MS -> SGSN: Identity Response IMSI (optional)
1687 * MS <- SGSN: Identity Request IMEI
1688 * MS -x SGSN: no response
1689 * MS <- SGSN: re-send: Identity Request IMEI 4x
1690 * MS <- SGSN: Attach Reject
1691 */
1692 var BSSGP_ConnHdlr vc_conn;
1693 f_init();
1694 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001695 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 +02001696 vc_conn.done;
1697}
1698
Alexander Couzens53f20562018-06-12 16:24:12 +02001699/* Attempt an attach, but loose the Identification Request (IMSI) */
1700private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1701 var integer count_req := 0;
1702 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1703
1704 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1705 g_pars.p_tmsi := 'c0000035'O;
1706
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001707 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 +02001708
1709 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001710 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001711 /* break */
1712 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001713 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001714 /* ignore ID REQ IMSI */
1715 count_req := count_req + 1;
1716 repeat;
1717 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001718 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001719 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001720 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001721 repeat;
1722 }
1723 }
1724 if (count_req != 5) {
1725 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001726 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001727 }
1728 setverdict(pass);
1729}
1730
1731testcase TC_attach_no_imsi_response() runs on test_CT {
1732 /* MS -> SGSN: Attach Request TMSI (unknown)
1733 * MS <- SGSN: Identity Request IMEI (optional)
1734 * MS -> SGSN: Identity Response IMEI (optional)
1735 * MS <- SGSN: Identity Request IMSI
1736 * MS -x SGSN: no response
1737 * MS <- SGSN: re-send: Identity Request IMSI 4x
1738 * MS <- SGSN: Attach Reject
1739 */
1740 var BSSGP_ConnHdlr vc_conn;
1741 f_init();
1742 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001743 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb, 35, 60.0);
Alexander Couzens53f20562018-06-12 16:24:12 +02001744 vc_conn.done;
1745}
1746
Alexander Couzenscf818962018-06-05 18:00:00 +02001747private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1748 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1749}
1750
1751testcase TC_attach_check_subscriber_list() runs on test_CT {
1752 /* MS <-> SGSN: Attach
1753 * VTY -> SGSN: Check if MS is in subscriber cache
1754 */
1755 var BSSGP_ConnHdlr vc_conn;
1756 var integer id := 34;
1757 var charstring imsi := hex2str(f_gen_imsi(id));
1758
1759 f_init();
1760 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001761 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001762 vc_conn.done;
1763
1764 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1765 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1766}
1767
Alexander Couzensf9858652018-06-07 16:14:53 +02001768private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1769 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1770 var BssgpDecoded bd;
1771
1772 /* unregister the old IMSI */
1773 f_bssgp_client_unregister(g_pars.imsi);
1774 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001775 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001776 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001777
1778 /* there is no auth */
1779 g_pars.net.expect_auth := false;
1780
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001781 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 +02001782 f_gmm_auth();
1783 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001784 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001785 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001786 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001787 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001788 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001789 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001790 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001791 setverdict(pass);
1792 }
1793 }
1794}
Alexander Couzens03d12242018-08-07 16:13:52 +02001795
1796private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1797
1798 f_TC_attach_closed_foreign(id);
1799 f_TC_attach_closed_imsi_added(id);
1800
1801}
1802
1803
Alexander Couzensf9858652018-06-07 16:14:53 +02001804testcase TC_attach_closed_add_vty() runs on test_CT {
1805 /* VTY-> SGSN: policy close
1806 * MS -> SGSN: Attach Request
1807 * MS <- SGSN: Identity Request IMSI
1808 * MS -> SGSN: Identity Response IMSI
1809 * MS <- SGSN: Attach Reject
1810 * VTY-> SGSN: policy imsi-acl add IMSI
1811 * MS -> SGSN: Attach Request
1812 * MS <- SGSN: Identity Request IMSI
1813 * MS -> SGSN: Identity Response IMSI
1814 * MS <- SGSN: Identity Request IMEI
1815 * MS -> SGSN: Identity Response IMEI
1816 * MS <- SGSN: Attach Accept
1817 */
1818 var BSSGP_ConnHdlr vc_conn;
1819 f_init();
1820 f_sleep(1.0);
1821 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1822 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001823 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1824 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001825 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001826 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001827 vc_conn.done;
1828}
1829
Alexander Couzens0085bd72018-06-12 19:08:44 +02001830/* Attempt an attach, but never answer a Attach Complete */
1831private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1832 var integer count_req := 0;
1833
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001834 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 +02001835 f_gmm_auth();
1836
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001837 timer T := 10.0;
1838 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001839 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001840 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001841 /* break */
1842 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001843 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001844 /* ignore */
1845 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001846 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001847 repeat;
1848 }
1849 }
1850 if (count_req != 5) {
1851 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001852 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001853 }
1854 setverdict(pass);
1855}
1856
1857testcase TC_attach_check_complete_resend() runs on test_CT {
1858 /* MS -> SGSN: Attach Request IMSI
1859 * MS <- SGSN: Identity Request *
1860 * MS -> SGSN: Identity Response *
1861 * MS <- SGSN: Attach Complete 5x
1862 */
1863 var BSSGP_ConnHdlr vc_conn;
1864 f_init();
1865 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001866 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 +02001867 vc_conn.done;
1868}
1869
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001870private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
1871 var BssgpDecoded bd;
1872
1873 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001874 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 +02001875 alt {
1876 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001877 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001878 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001879 setverdict(pass);
1880 }
1881 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
1882 setverdict(fail, "Unexpected RAU Reject");
1883 mtc.stop;
1884 }
1885 [] BSSGP[bssgp].receive { repeat; }
1886 }
1887}
1888
Alexander Couzensbfda9212018-07-31 03:17:33 +02001889private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
1890 var BssgpDecoded bd;
1891
1892 /* first perform regular attach */
1893 f_TC_attach(id);
1894
1895 /* then send RAU */
1896 f_routing_area_update(g_pars.ra);
1897
1898 /* do another RAU */
1899 f_routing_area_update(g_pars.ra);
1900
1901 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1902}
1903
1904testcase TC_attach_rau_a_a() runs on test_CT {
1905 /* MS <-> SGSN: Successful Attach
1906 * MS -> SGSN: Routing Area Update Request
1907 * MS <- SGSN: Routing Area Update Accept
1908 * MS -> SGSN: Routing Area Update Request
1909 * MS <- SGSN: Routing Area Update Accept
1910 * MS -> SGSN: Detach (PowerOff)
1911 */
1912 var BSSGP_ConnHdlr vc_conn;
1913 f_init();
1914 f_sleep(1.0);
1915 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
1916 vc_conn.done;
1917}
1918
Alexander Couzensbe837bd2018-07-31 04:20:11 +02001919private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
1920 var BssgpDecoded bd;
1921
1922 f_TC_attach(id);
1923
1924 log("attach complete sending rau");
1925 f_routing_area_update(g_pars.ra, 0);
1926
1927 log("rau complete unregistering");
1928 f_bssgp_client_unregister(g_pars.imsi);
1929 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
1930
1931 log("sending second RAU via different RA");
1932 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
1933
1934 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
1935}
1936
1937testcase TC_attach_rau_a_b() runs on test_CT {
1938 /* MS <-> SGSN: Successful Attach
1939 * MS -> SGSN: Routing Area _a_ Update Request
1940 * MS <- SGSN: Routing Area _a_ Update Accept
1941 * MS -> SGSN: Routing Area _b_ Update Request
1942 * MS <- SGSN: Routing Area _b_ Update Accept
1943 * MS -> SGSN: Detach (PowerOff)
1944 */
1945 var BSSGP_ConnHdlr vc_conn;
1946 f_init();
1947 f_sleep(1.0);
1948 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
1949 vc_conn.done;
1950}
1951
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02001952private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
1953 var integer count_req := 0;
1954 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1955 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
1956 var BssgpDecoded bd;
1957
1958 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1959
1960 alt {
1961 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1962 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1963 mtc.stop;
1964 }
1965 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1966 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1967 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1968 repeat;
1969 }
1970 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1971 /* send out a second GMM_Attach Request.
1972 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
1973 * of the same content */
1974 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1975 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1976 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1977 }
1978 }
1979 f_sleep(1.0);
1980
1981 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
1982 alt {
1983 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1984 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1985 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1986 repeat;
1987 }
1988 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1989 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
1990 mtc.stop;
1991 }
1992 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1993 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1994 mtc.stop;
1995 }
1996 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
1997 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1998 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
1999 setverdict(pass);
2000 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2001 }
2002 }
2003}
2004
2005testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2006 /* Testing if the SGSN ignore Attach Request with the exact same content */
2007 /* MS -> SGSN: Attach Request IMSI
2008 * MS <- SGSN: Identity Request IMSI (optional)
2009 * MS -> SGSN: Identity Response IMSI (optional)
2010 * MS <- SGSN: Identity Request IMEI
2011 * MS -> SGSN: Attach Request (2nd)
2012 * MS <- SGSN: Identity Response IMEI
2013 * MS <- SGSN: Attach Accept
2014 * MS -> SGSN: Attach Complete
2015 */
2016 var BSSGP_ConnHdlr vc_conn;
2017 f_init();
2018 f_sleep(1.0);
2019 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2020 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2021 vc_conn.done;
2022}
2023
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002024private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
2025 var BssgpDecoded bd;
2026 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2027
2028 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2029
2030 /* send Attach Request */
2031 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2032 * 3G auth vectors */
2033 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2034 /* The thing is, if the solSACapability is 'omit', then the
2035 * revisionLevelIndicatior is at the wrong place! */
2036 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2037 f_send_l3_gmm_llc(attach_req);
2038
2039 /* do the auth */
2040 var PDU_L3_MS_SGSN l3_mo;
2041 var PDU_L3_SGSN_MS l3_mt;
2042 var default di := activate(as_mm_identity());
2043
2044 var GSUP_IE auth_tuple;
2045 var template AuthenticationParameterAUTNTLV autn;
2046
2047 g_pars.vec := f_gen_auth_vec_3g();
2048 autn := {
2049 elementIdentifier := '28'O,
2050 lengthIndicator := lengthof(g_pars.vec.autn),
2051 autnValue := g_pars.vec.autn
2052 };
2053 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2054 g_pars.vec.sres,
2055 g_pars.vec.kc,
2056 g_pars.vec.ik,
2057 g_pars.vec.ck,
2058 g_pars.vec.autn,
2059 g_pars.vec.res));
2060 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2061 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2062 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2063
2064 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2065 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2066 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2067
2068 /* send the gmm auth failure with resync IE */
2069 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2070
2071 /* wait for the GSUP resync request */
2072 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2073 g_pars.imsi,
2074 g_pars.vec.auts,
2075 g_pars.vec.rand));
2076
2077 /* generate new key material */
2078 g_pars.vec := f_gen_auth_vec_3g();
2079 autn := {
2080 elementIdentifier := '28'O,
2081 lengthIndicator := lengthof(g_pars.vec.autn),
2082 autnValue := g_pars.vec.autn
2083 };
2084
2085 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2086 g_pars.vec.sres,
2087 g_pars.vec.kc,
2088 g_pars.vec.ik,
2089 g_pars.vec.ck,
2090 g_pars.vec.autn,
2091 g_pars.vec.res));
2092 /* send new key material */
2093 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2094
2095 /* wait for the new Auth Request */
2096 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2097 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2098 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2099 l3_mt := bd.l3_mt;
2100 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2101 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2102 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2103 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2104 valueField := substr(g_pars.vec.res, 0, 4)
2105 };
2106 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2107 elementIdentifier := '21'O,
2108 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2109 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2110 };
2111 l3_mo := valueof(auth_ciph_resp);
2112 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2113 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2114 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2115 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2116 }
2117 f_send_l3_gmm_llc(l3_mo);
2118 deactivate(di);
2119
2120 /* Expect SGSN to perform LU with HLR */
2121 f_gmm_gsup_lu_isd();
2122
2123 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2124 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2125 }
2126 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2127 setverdict(pass);
2128}
2129
2130testcase TC_attach_usim_resync() runs on test_CT {
2131 /* MS -> SGSN: Attach Request
2132 * MS <- SGSN: Identity Request IMSI
2133 * MS -> SGSN: Identity Response IMSI
2134 * MS <- SGSN: Identity Request IMEI
2135 * MS -> SGSN: Identity Response IMEI
2136 * HLR<- SGSN: SAI Request
2137 * HLR-> SGSN: SAI Response
2138 * MS <- SGSN: Auth Request
2139 * MS -> SGSN: Auth Failure (with AUTS)
2140 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2141 * HLR-> SGSN: SAI Response (new key material)
2142 * MS <- SGSN: Auth Request (new key material)
2143 * MS -> SGSN: Auth Response
2144 * MS <- SGSN: Attach Accept
2145 * MS -> SGSN: Attach Complete
2146 */
2147 var BSSGP_ConnHdlr vc_conn;
2148 f_init();
2149 f_sleep(1.0);
2150 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2151 vc_conn.done;
2152}
2153
Harald Welte5ac31492018-02-15 20:39:13 +01002154control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002155 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002156 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002157 execute( TC_attach_umts_aka_umts_res() );
2158 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002159 execute( TC_attach_auth_id_timeout() );
2160 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002161 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002162 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002163 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002164 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002165 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002166 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002167 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002168 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002169 execute( TC_attach_closed_add_vty(), 20.0 );
2170 execute( TC_attach_check_subscriber_list(), 20.0 );
2171 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002172 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002173 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2174 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2175 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2176 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002177 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002178 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002179 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002180 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002181 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002182 execute( TC_detach_unknown_nopoweroff() );
2183 execute( TC_detach_unknown_poweroff() );
2184 execute( TC_detach_nopoweroff() );
2185 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002186 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002187 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002188 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002189 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002190 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002191 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002192 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002193 execute( TC_attach_restart_ctr_echo() );
2194 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002195 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002196 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002197 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Welte5ac31492018-02-15 20:39:13 +01002198}
Harald Welte96a33b02018-02-04 10:36:22 +01002199
2200
2201
2202}