blob: 2bdbfb9b677eb0cf821731c6c87ce2937d9c89e0 [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
Harald Welte2fa771f2019-05-02 20:13:53 +020087const integer NUM_GB := 3;
88type record length(NUM_GB) of GbInstance GbInstances;
89type record length(NUM_GB) of NSConfiguration NSConfigurations;
90type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +020091
Harald Welte96a33b02018-02-04 10:36:22 +010092type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +020093 var GbInstances g_gb;
Harald Welte96a33b02018-02-04 10:36:22 +010094
Harald Welte5ac31492018-02-15 20:39:13 +010095 var GSUP_Emulation_CT vc_GSUP;
96 var IPA_Emulation_CT vc_GSUP_IPA;
97 /* only to get events from IPA underneath GSUP */
98 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010099
Harald Welteeded9ad2018-02-17 20:57:34 +0100100 var GTP_Emulation_CT vc_GTP;
101
Harald Weltebd194722018-02-16 22:11:08 +0100102 port TELNETasp_PT SGSNVTY;
103
Harald Welte96a33b02018-02-04 10:36:22 +0100104 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200105 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100106};
107
Harald Welteeded9ad2018-02-17 20:57:34 +0100108type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100109 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100110 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200111 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100112}
113
114type record SGSN_ConnHdlrNetworkPars {
115 boolean expect_ptmsi,
116 boolean expect_auth,
117 boolean expect_ciph
118};
119
120type record BSSGP_ConnHdlrPars {
121 /* IMEI of the simulated ME */
122 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200123 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100124 hexstring imsi,
125 /* MSISDN of the simulated MS (probably unused) */
126 hexstring msisdn,
127 /* P-TMSI allocated to the simulated MS */
128 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100129 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100130 /* TLLI of the simulated MS */
131 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100132 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100133 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200134 BssgpCellIds bssgp_cell_id,
Harald Welte5ac31492018-02-15 20:39:13 +0100135 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100136 SGSN_ConnHdlrNetworkPars net,
137 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100138};
139
Alexander Couzens89508702018-07-31 04:16:10 +0200140private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200141 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200142 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
143
144 var RoutingAreaIdentificationV ret := {
145 mccDigit1 := mcc_mnc[0],
146 mccDigit2 := mcc_mnc[1],
147 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200148 mncDigit3 := mcc_mnc[3],
149 mncDigit1 := mcc_mnc[4],
150 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200151 lac := int2oct(cell_id.ra_id.lai.lac, 16),
152 rac := int2oct(cell_id.ra_id.rac, 8)
153 }
154 return ret;
155};
156
Alexander Couzens51114d12018-07-31 18:41:56 +0200157private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
158 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
159 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100160 /* connect lower end of BSSGP emulation with NS upper port */
161 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
162 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
163 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
164
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200165 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100166 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
167}
168
169private function f_init_gsup(charstring id) runs on test_CT {
170 id := id & "-GSUP";
171 var GsupOps ops := {
172 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
173 };
174
175 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
176 vc_GSUP := GSUP_Emulation_CT.create(id);
177
178 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
179 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
180 /* we use this hack to get events like ASP_IPA_EVENT_UP */
181 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
182
183 vc_GSUP.start(GSUP_Emulation.main(ops, id));
184 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
185
186 /* wait for incoming connection to GSUP port before proceeding */
187 timer T := 10.0;
188 T.start;
189 alt {
190 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
191 [] T.timeout {
192 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200193 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100194 }
195 }
196}
197
Harald Welteeded9ad2018-02-17 20:57:34 +0100198private function f_init_gtp(charstring id) runs on test_CT {
199 id := id & "-GTP";
200
201 var GtpEmulationCfg gtp_cfg := {
202 gtpc_bind_ip := mp_ggsn_ip,
203 gtpc_bind_port := GTP1C_PORT,
204 gtpu_bind_ip := mp_ggsn_ip,
205 gtpu_bind_port := GTP1U_PORT,
206 sgsn_role := false
207 };
208
209 vc_GTP := GTP_Emulation_CT.create(id);
210 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
211}
212
Harald Weltebd194722018-02-16 22:11:08 +0100213private function f_init_vty() runs on test_CT {
214 map(self:SGSNVTY, system:SGSNVTY);
215 f_vty_set_prompts(SGSNVTY);
216 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200217 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100218 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
219}
220
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200221private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
222 if (enable) {
223 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
224 } else {
225 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
226 }
227}
228
Harald Weltebd194722018-02-16 22:11:08 +0100229
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200230/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
231function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100232 if (g_initialized == true) {
233 return;
234 }
235 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100236 g_gb[0].cfg := {
237 nsei := 96,
238 bvci := 196,
239 cell_id := {
240 ra_id := {
241 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100242 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100243 rac := 0
244 },
245 cell_id := 20960
246 },
247 sgsn_role := false
248 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200249 g_gb[1].cfg := {
250 nsei := 97,
251 bvci := 210,
252 cell_id := {
253 ra_id := {
254 lai := {
255 mcc_mnc := mcc_mnc, lac := 13200},
256 rac := 0
257 },
258 cell_id := 20961
259 },
260 sgsn_role := false
261 };
262 g_gb[2].cfg := {
263 nsei := 98,
264 bvci := 220,
265 cell_id := {
266 ra_id := {
267 lai := {
268 mcc_mnc := mcc_mnc, lac := 13300},
269 rac := 0
270 },
271 cell_id := 20962
272 },
273 sgsn_role := false
274 };
Harald Welte96a33b02018-02-04 10:36:22 +0100275
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200276 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200277 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
278 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
279 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte5ac31492018-02-15 20:39:13 +0100280 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100281 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200282 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100283}
Harald Welte96a33b02018-02-04 10:36:22 +0100284
Harald Welte5ac31492018-02-15 20:39:13 +0100285type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
286
287/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200288function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100289 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100290runs on test_CT return BSSGP_ConnHdlr {
291 var BSSGP_ConnHdlr vc_conn;
292 var SGSN_ConnHdlrNetworkPars net_pars := {
293 expect_ptmsi := true,
294 expect_auth := true,
295 expect_ciph := false
296 };
297 var BSSGP_ConnHdlrPars pars := {
298 imei := f_gen_imei(imsi_suffix),
299 imsi := f_gen_imsi(imsi_suffix),
300 msisdn := f_gen_msisdn(imsi_suffix),
301 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100302 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100303 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100304 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100305 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200306 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 +0100307 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100308 net := net_pars,
309 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100310 };
311
312 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200313 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
314 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
315 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
316 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
317 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
318 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100319
320 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
321 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
322
Harald Welteeded9ad2018-02-17 20:57:34 +0100323 connect(vc_conn:GTP, vc_GTP:CLIENT);
324 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
325
Harald Welte5ac31492018-02-15 20:39:13 +0100326 vc_conn.start(f_handler_init(fn, id, pars));
327 return vc_conn;
328}
329
Harald Welte62e29582018-02-16 21:17:11 +0100330private altstep as_Tguard() runs on BSSGP_ConnHdlr {
331 [] g_Tguard.timeout {
332 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200333 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100334 }
335}
336
Harald Welte5ac31492018-02-15 20:39:13 +0100337/* first function called in every ConnHdlr */
338private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
339runs on BSSGP_ConnHdlr {
340 /* do some common stuff like setting up g_pars */
341 g_pars := pars;
342
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200343 llc := f_llc_create(false);
344
Harald Welte5ac31492018-02-15 20:39:13 +0100345 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200346 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100347 /* tell GSUP dispatcher to send this IMSI to us */
348 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100349 /* tell GTP dispatcher to send this IMSI to us */
350 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100351
Harald Welte62e29582018-02-16 21:17:11 +0100352 g_Tguard.start(pars.t_guard);
353 activate(as_Tguard());
354
Harald Welte5ac31492018-02-15 20:39:13 +0100355 /* call the user-supplied test case function */
356 fn.apply(id);
357 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100358}
359
360/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100361 * Detach without Attach
362 * SM procedures without attach / RAU
363 * ATTACH / RAU
364 ** with / without authentication
365 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100366 * re-transmissions of LLC frames
367 * PDP Context activation
368 ** with different GGSN config in SGSN VTY
369 ** with different PDP context type (v4/v6/v46)
370 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100371 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100372 */
373
374testcase TC_wait_ns_up() runs on test_CT {
375 f_init();
376 f_sleep(20.0);
377}
378
Harald Weltea05b8072019-04-23 22:35:05 +0200379function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
380 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
381 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
382}
383
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200384function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
385 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
386 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
387 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200388 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200389}
390
Harald Welteca362462019-05-02 20:11:21 +0200391altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100392 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welteca362462019-05-02 20:11:21 +0200393 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100394 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteca362462019-05-02 20:11:21 +0200395 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100396 repeat;
397 }
Harald Welteca362462019-05-02 20:11:21 +0200398 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100399 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welteca362462019-05-02 20:11:21 +0200400 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100401 repeat;
402 }
403}
Harald Welte96a33b02018-02-04 10:36:22 +0100404
Harald Welteca362462019-05-02 20:11:21 +0200405/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
406function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
407runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
408 var BssgpDecoded bd;
409 var PDU_L3_SGSN_MS l3_mt;
410 alt {
411 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(rx_tpl)) -> value bd {
412 l3_mt := bd.l3_mt;
413 }
414 }
415 return l3_mt;
416}
417
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200418/* perform GMM authentication (if expected).
419 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
420 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200421function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100422 var PDU_L3_MS_SGSN l3_mo;
423 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200424 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100425 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200426 var GSUP_IE auth_tuple;
427 var template AuthenticationParameterAUTNTLV autn;
428
429 if (umts_aka_challenge) {
430 g_pars.vec := f_gen_auth_vec_3g();
431 autn := {
432 elementIdentifier := '28'O,
433 lengthIndicator := lengthof(g_pars.vec.autn),
434 autnValue := g_pars.vec.autn
435 };
436
437 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
438 g_pars.vec.sres,
439 g_pars.vec.kc,
440 g_pars.vec.ik,
441 g_pars.vec.ck,
442 g_pars.vec.autn,
443 g_pars.vec.res));
444 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
445 } else {
446 g_pars.vec := f_gen_auth_vec_2g();
447 autn := omit;
448 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
449 g_pars.vec.sres,
450 g_pars.vec.kc));
451 log("GSUP sends only 2G auth tuple", auth_tuple);
452 }
Harald Welteca362462019-05-02 20:11:21 +0200453
Harald Welte5ac31492018-02-15 20:39:13 +0100454 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
455 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200456
457 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
458 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200459 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100460 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200461 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
462
463 if (umts_aka_challenge and not force_gsm_sres) {
464 /* set UMTS response instead */
465 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
466 valueField := substr(g_pars.vec.res, 0, 4)
467 };
468 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
469 elementIdentifier := '21'O,
470 lengthIndicator := lengthof(g_pars.vec.res) - 4,
471 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
472 };
473 }
474
475 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100476 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
477 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
478 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
479 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
480 }
Harald Welteca362462019-05-02 20:11:21 +0200481 f_send_l3_gmm_llc(l3_mo, gb_idx);
Harald Welte76dee092018-02-16 22:12:59 +0100482 } else {
483 /* wait for identity procedure */
484 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100485 }
Harald Welte76dee092018-02-16 22:12:59 +0100486
Harald Welte5ac31492018-02-15 20:39:13 +0100487 deactivate(di);
488}
489
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200490function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100491 g_pars.p_tmsi := p_tmsi;
492 /* update TLLI */
493 g_pars.tlli_old := g_pars.tlli;
494 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200495 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100496}
497
Harald Welte04683d02018-02-16 22:43:45 +0100498function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
499 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100500 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200501 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100502 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200503 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200504 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100505 }
Harald Welte04683d02018-02-16 22:43:45 +0100506 g_pars.ra := aa.routingAreaIdentification;
507 if (ispresent(aa.allocatedPTMSI)) {
508 if (not g_pars.net.expect_ptmsi) {
509 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200510 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100511 }
Harald Weltef70997d2018-02-17 10:11:19 +0100512 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100513 }
514 if (ispresent(aa.msIdentity)) {
515 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200516 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100517 }
518 /* P-TMSI.sig */
519 if (ispresent(aa.ptmsiSignature)) {
520 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
521 }
522 /* updateTimer */
523 // aa.readyTimer
524 /* T3302, T3319, T3323, T3312_ext, T3324 */
525}
526
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200527function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100528 /* mandatory IE */
529 g_pars.ra := ra.routingAreaId;
530 if (ispresent(ra.allocatedPTMSI)) {
531 if (not g_pars.net.expect_ptmsi) {
532 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200533 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100534 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200535 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100536 }
537 if (ispresent(ra.msIdentity)) {
538 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200539 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100540 }
541 /* P-TMSI.sig */
542 if (ispresent(ra.ptmsiSignature)) {
543 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
544 }
545 /* updateTimer */
546 // aa.readyTimer
547 /* T3302, T3319, T3323, T3312_ext, T3324 */
548}
549
550
Harald Welte5a4fa042018-02-16 20:59:21 +0100551function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
552 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
553}
554
Harald Welte23178c52018-02-17 09:36:33 +0100555/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100556private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100557 if (ispresent(g_pars.p_tmsi)) {
558 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
559 } else {
560 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
561 }
562}
563
Harald Welte311ec272018-02-17 09:40:03 +0100564private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100565 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100566 /* Expect MSC to perform LU with HLR */
567 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100568 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
569 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
570 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100571 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
572 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
573}
574
Harald Welteca362462019-05-02 20:11:21 +0200575friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100576 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200577 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welteca362462019-05-02 20:11:21 +0200578 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100579
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200580 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
581 * 3G auth vectors */
582 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
583 /* The thing is, if the solSACapability is 'omit', then the
584 * revisionLevelIndicatior is at the wrong place! */
585 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
586
Harald Welteca362462019-05-02 20:11:21 +0200587 f_send_l3_gmm_llc(attach_req, gb_idx);
588 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200589 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100590 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100591
Harald Welteca362462019-05-02 20:11:21 +0200592 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
593 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
594
Harald Welte04683d02018-02-16 22:43:45 +0100595 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welteca362462019-05-02 20:11:21 +0200596 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL, gb_idx);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200597}
598
599private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
600 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100601 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100602}
603
604testcase TC_attach() runs on test_CT {
605 var BSSGP_ConnHdlr vc_conn;
606 f_init();
607 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200608 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100609 vc_conn.done;
610}
611
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100612testcase TC_attach_mnc3() runs on test_CT {
613 var BSSGP_ConnHdlr vc_conn;
614 f_init('023042'H);
615 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200616 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100617 vc_conn.done;
618}
619
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200620private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
621 f_gmm_attach(true, false);
622 setverdict(pass);
623}
624testcase TC_attach_umts_aka_umts_res() runs on test_CT {
625 var BSSGP_ConnHdlr vc_conn;
626 f_init();
627 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200628 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200629 vc_conn.done;
630}
631
632private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
633 f_gmm_attach(true, true);
634 setverdict(pass);
635}
636testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
637 var BSSGP_ConnHdlr vc_conn;
638 f_init();
639 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200640 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200641 vc_conn.done;
642}
643
Harald Welte5b7c8122018-02-16 21:48:17 +0100644/* MS never responds to ID REQ, expect ATTACH REJECT */
645private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100646 var RoutingAreaIdentificationV old_ra := f_random_RAI();
647
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200648 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 +0100649 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200650 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100651 /* don't send ID Response */
652 repeat;
653 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200654 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100655 setverdict(pass);
656 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200657 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100658 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200659 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100660 }
661 }
662}
663testcase TC_attach_auth_id_timeout() runs on test_CT {
664 var BSSGP_ConnHdlr vc_conn;
665 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200666 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 +0100667 vc_conn.done;
668}
669
670/* HLR never responds to SAI REQ, expect ATTACH REJECT */
671private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100672 var RoutingAreaIdentificationV old_ra := f_random_RAI();
673
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200674 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 +0100675 alt {
676 [] as_mm_identity();
677 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
678 }
679 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200680 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100681 setverdict(pass);
682}
683testcase TC_attach_auth_sai_timeout() runs on test_CT {
684 var BSSGP_ConnHdlr vc_conn;
685 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200686 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100687 vc_conn.done;
688}
689
Harald Weltefe253882018-02-17 09:25:00 +0100690/* HLR rejects SAI, expect ATTACH REJECT */
691private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100692 var RoutingAreaIdentificationV old_ra := f_random_RAI();
693
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200694 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 +0100695 alt {
696 [] as_mm_identity();
697 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
698 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
699 }
700 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200701 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100702 setverdict(pass);
703}
704testcase TC_attach_auth_sai_reject() runs on test_CT {
705 var BSSGP_ConnHdlr vc_conn;
706 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200707 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100708 vc_conn.done;
709}
710
Harald Welte5b7c8122018-02-16 21:48:17 +0100711/* HLR never responds to UL REQ, expect ATTACH REJECT */
712private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100713 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100714 var RoutingAreaIdentificationV old_ra := f_random_RAI();
715
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200716 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 +0100717 f_gmm_auth();
718 /* Expect MSC to perform LU with HLR */
719 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
720 /* Never follow-up with ISD_REQ or UL_RES */
721 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200722 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100723 setverdict(pass);
724 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200725 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100726 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100727 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200728 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100729 }
730 }
731}
732testcase TC_attach_gsup_lu_timeout() runs on test_CT {
733 var BSSGP_ConnHdlr vc_conn;
734 f_init();
735 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200736 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100737 vc_conn.done;
738}
739
Harald Welteb7c14e92018-02-17 09:29:16 +0100740/* HLR rejects UL REQ, expect ATTACH REJECT */
741private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
742 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100743 var RoutingAreaIdentificationV old_ra := f_random_RAI();
744
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200745 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 +0100746 f_gmm_auth();
747 /* Expect MSC to perform LU with HLR */
748 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
749 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
750 }
751 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200752 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100753 setverdict(pass);
754 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200755 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100756 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
757 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200758 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100759 }
760 }
761}
762testcase TC_attach_gsup_lu_reject() runs on test_CT {
763 var BSSGP_ConnHdlr vc_conn;
764 f_init();
765 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200766 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100767 vc_conn.done;
768}
769
770
Harald Welte3823e2e2018-02-16 21:53:48 +0100771/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
772private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100773 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100774 var RoutingAreaIdentificationV old_ra := f_random_RAI();
775
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200776 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 +0100777 f_gmm_auth();
778 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100779 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100780
Alexander Couzens0e510e62018-07-28 23:06:00 +0200781 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100782 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
783 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200784 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100785 setverdict(pass);
786}
Harald Welte3823e2e2018-02-16 21:53:48 +0100787testcase TC_attach_combined() runs on test_CT {
788 var BSSGP_ConnHdlr vc_conn;
789 f_init();
790 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200791 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100792 vc_conn.done;
793}
794
Harald Welte76dee092018-02-16 22:12:59 +0100795/* Attempt of GPRS ATTACH in 'accept all' mode */
796private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100797 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100798 var RoutingAreaIdentificationV old_ra := f_random_RAI();
799
800 g_pars.net.expect_auth := false;
801
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200802 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 +0100803 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200804 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100805 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
806 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200807 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100808 setverdict(pass);
809}
810testcase TC_attach_accept_all() runs on test_CT {
811 var BSSGP_ConnHdlr vc_conn;
812 f_init();
813 f_sleep(1.0);
814 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200815 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100816 vc_conn.done;
817}
Harald Welte5b7c8122018-02-16 21:48:17 +0100818
Harald Welteb2124b22018-02-16 22:26:56 +0100819/* Attempt of GPRS ATTACH in 'accept all' mode */
820private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100821 var RoutingAreaIdentificationV old_ra := f_random_RAI();
822
823 /* Simulate a foreign IMSI */
824 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200825 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100826
827 g_pars.net.expect_auth := false;
828
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200829 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 +0100830 alt {
831 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200832 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100833 setverdict(pass);
834 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200835 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100836 setverdict(pass);
837 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200838 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200839 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200840 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200841 }
Harald Welteb2124b22018-02-16 22:26:56 +0100842 }
843}
844testcase TC_attach_closed() runs on test_CT {
845 var BSSGP_ConnHdlr vc_conn;
846 f_init();
847 f_sleep(1.0);
848 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
849 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200850 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100851 vc_conn.done;
852 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200853 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100854 vc_conn.done;
855}
856
Harald Welte04683d02018-02-16 22:43:45 +0100857/* Routing Area Update from Unknown TLLI -> REJECT */
858private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100859 var RoutingAreaIdentificationV old_ra := f_random_RAI();
860
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200861 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 +0100862 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200863 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100864 setverdict(pass);
865 }
866 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200867 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100868 }
869}
870testcase TC_rau_unknown() runs on test_CT {
871 var BSSGP_ConnHdlr vc_conn;
872 f_init();
873 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200874 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100875 vc_conn.done;
876}
877
Harald Welte91636de2018-02-17 10:16:14 +0100878private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
879 var BssgpDecoded bd;
880
881 /* first perform regular attach */
882 f_TC_attach(id);
883
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200884 f_routing_area_update(g_pars.ra);
885
Harald Welte91636de2018-02-17 10:16:14 +0100886}
887testcase TC_attach_rau() runs on test_CT {
888 var BSSGP_ConnHdlr vc_conn;
889 f_init();
890 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200891 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100892 vc_conn.done;
893}
Harald Welte04683d02018-02-16 22:43:45 +0100894
Harald Welte6abb9fe2018-02-17 15:24:48 +0100895/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200896function 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 +0100897 var BssgpDecoded bd;
898 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200899 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100900 if (expect_purge) {
901 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
902 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
903 }
904 T.start;
905 alt {
906 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
907 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200908 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100909 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200910 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100911 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +0200912 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200913 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100914 /* TODO: check if any PDP contexts are deactivated on network side? */
915 }
Alexander Couzens44aa0772019-05-11 01:21:03 +0200916 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(?)) -> value bd {
917 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
918 mtc.stop;
919 }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100920 [power_off] T.timeout {
921 setverdict(pass);
922 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200923 [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 +0100924 g_pars.ra := omit;
925 setverdict(pass);
926 /* TODO: check if any PDP contexts are deactivated on network side? */
927 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200928 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100929 }
930}
931
932/* IMSI DETACH (non-power-off) for unknown TLLI */
933private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
934 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
935}
936testcase TC_detach_unknown_nopoweroff() runs on test_CT {
937 var BSSGP_ConnHdlr vc_conn;
938 f_init();
939 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200940 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100941 vc_conn.done;
942}
943
944/* IMSI DETACH (power-off) for unknown TLLI */
945private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
946 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
947}
948testcase TC_detach_unknown_poweroff() runs on test_CT {
949 var BSSGP_ConnHdlr vc_conn;
950 f_init();
951 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200952 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100953 vc_conn.done;
954}
955
956/* IMSI DETACH (non-power-off) for known TLLI */
957private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
958 /* first perform regular attach */
959 f_TC_attach(id);
960
961 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
962}
963testcase TC_detach_nopoweroff() runs on test_CT {
964 var BSSGP_ConnHdlr vc_conn;
965 f_init();
966 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200967 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100968 vc_conn.done;
969}
970
971/* IMSI DETACH (power-off) for known TLLI */
972private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
973 /* first perform regular attach */
974 f_TC_attach(id);
975
976 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
977}
978testcase TC_detach_poweroff() runs on test_CT {
979 var BSSGP_ConnHdlr vc_conn;
980 f_init();
981 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200982 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100983 vc_conn.done;
984}
985
Harald Welteeded9ad2018-02-17 20:57:34 +0100986type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100987 BIT3 tid, /* L3 Transaction ID */
988 BIT4 nsapi, /* SNDCP NSAPI */
989 BIT4 sapi, /* LLC SAPI */
990 QoSV qos, /* QoS parameters */
991 PDPAddressV addr, /* IP address */
992 octetstring apn optional, /* APN name */
993 ProtocolConfigOptionsV pco optional, /* protoco config opts */
994 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100995 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100996 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100997
Harald Welte822f9102018-02-18 20:39:06 +0100998 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
999 OCT4 ggsn_tei_u, /* GGSN TEI User */
1000 octetstring ggsn_ip_c, /* GGSN IP Control */
1001 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001002 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001003
Harald Welte822f9102018-02-18 20:39:06 +01001004 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1005 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1006 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1007 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001008};
1009
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001010
1011private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1012 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1013 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1014 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1015 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1016 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1017 f_gtp_register_teid(apars.ggsn_tei_c);
1018 f_gtp_register_teid(apars.ggsn_tei_u);
1019}
1020
Harald Weltef7191672019-05-02 20:37:23 +02001021function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1022runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001023 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1024 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001025 var template Recovery_gtpc recovery := omit;
1026
1027 if (send_recovery) {
1028 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1029 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001030
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001031 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001032 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001033 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1034 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1035 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1036 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1037 apars.sgsn_tei_c, apars.gtp_resp_cause,
1038 apars.ggsn_tei_c, apars.ggsn_tei_u,
1039 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001040 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1041 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001042 }
1043 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001044 [exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001045 setverdict(pass);
1046 }
Harald Weltef7191672019-05-02 20:37:23 +02001047 [exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001048 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001049 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001050 }
Harald Weltef7191672019-05-02 20:37:23 +02001051 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001052 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001053 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001054 }
Harald Weltef7191672019-05-02 20:37:23 +02001055 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
1056 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1057 mtc.stop;
1058 }
1059 [not exp_rej] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001060 setverdict(pass);
1061 }
Harald Weltef7191672019-05-02 20:37:23 +02001062 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001063 }
1064}
1065
Harald Weltef7191672019-05-02 20:37:23 +02001066function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1067runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001068 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1069 var Gtp1cUnitdata g_ud;
1070
Harald Weltef7191672019-05-02 20:37:23 +02001071 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001072 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1073 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001074 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001075 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1076 }
1077 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001078 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001079 setverdict(pass);
1080 }
Harald Weltef7191672019-05-02 20:37:23 +02001081 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001082 }
1083}
1084
Harald Weltef7191672019-05-02 20:37:23 +02001085function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1086runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001087 var Gtp1cUnitdata g_ud;
1088 var integer seq_nr := 23;
1089 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1090
Harald Weltef7191672019-05-02 20:37:23 +02001091 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001092 if (error_ind) {
1093 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1094 } else {
1095 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1096 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001097
1098 timer T := 5.0;
1099 T.start;
1100
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001101 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001102 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
1103 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001104 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001105 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1106 repeat;
1107 }
1108 [] T.timeout {
1109 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1110 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001111 }
1112}
1113
Harald Welte6f203162018-02-18 22:04:55 +01001114
Harald Welteeded9ad2018-02-17 20:57:34 +01001115/* Table 10.5.156/3GPP TS 24.008 */
1116template (value) QoSV t_QosDefault := {
1117 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1118 delayClass := '100'B, /* best effort */
1119 spare1 := '00'B,
1120 precedenceClass := '010'B, /* normal */
1121 spare2 := '0'B,
1122 peakThroughput := '0000'B, /* subscribed */
1123 meanThroughput := '00000'B, /* subscribed */
1124 spare3 := '000'B,
1125 deliverErroneusSDU := omit,
1126 deliveryOrder := omit,
1127 trafficClass := omit,
1128 maxSDUSize := omit,
1129 maxBitrateUplink := omit,
1130 maxBitrateDownlink := omit,
1131 sduErrorRatio := omit,
1132 residualBER := omit,
1133 trafficHandlingPriority := omit,
1134 transferDelay := omit,
1135 guaranteedBitRateUplink := omit,
1136 guaranteedBitRateDownlink := omit,
1137 sourceStatisticsDescriptor := omit,
1138 signallingIndication := omit,
1139 spare4 := omit,
1140 maxBitrateDownlinkExt := omit,
1141 guaranteedBitRateDownlinkExt := omit,
1142 maxBitrateUplinkExt := omit,
1143 guaranteedBitRateUplinkExt := omit,
1144 maxBitrateDownlinkExt2 := omit,
1145 guaranteedBitRateDownlinkExt2 := omit,
1146 maxBitrateUplinkExt2 := omit,
1147 guaranteedBitRateUplinkExt2 := omit
1148}
1149
1150/* 10.5.6.4 / 3GPP TS 24.008 */
1151template (value) PDPAddressV t_AddrIPv4dyn := {
1152 pdpTypeOrg := '0001'B, /* IETF */
1153 spare := '0000'B,
1154 pdpTypeNum := '21'O, /* IPv4 */
1155 addressInfo := omit
1156}
1157template (value) PDPAddressV t_AddrIPv6dyn := {
1158 pdpTypeOrg := '0001'B, /* IETF */
1159 spare := '0000'B,
1160 pdpTypeNum := '53'O, /* IPv6 */
1161 addressInfo := omit
1162}
1163
Harald Welte37692d82018-02-18 15:21:34 +01001164template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001165 tid := '000'B,
1166 nsapi := '0101'B, /* < 5 are reserved */
1167 sapi := '0011'B, /* 3/5/9/11 */
1168 qos := t_QosDefault,
1169 addr := t_AddrIPv4dyn,
1170 apn := omit,
1171 pco := omit,
1172 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001173 gtp_resp_cause := int2oct(128, 1),
1174 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001175
1176 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001177 ggsn_tei_c := f_rnd_octstring(4),
1178 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001179 ggsn_ip_c := f_inet_addr(ggsn_ip),
1180 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001181 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001182
Harald Welteeded9ad2018-02-17 20:57:34 +01001183 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001184 sgsn_tei_u := omit,
1185 sgsn_ip_c := omit,
1186 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001187}
1188
Harald Welte37692d82018-02-18 15:21:34 +01001189template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1190 connId := 1,
1191 remName := f_inet_ntoa(ip),
1192 remPort := GTP1U_PORT
1193}
1194
1195template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1196 connId := 1,
1197 remName := f_inet_ntoa(ip),
1198 remPort := GTP1C_PORT
1199}
1200
1201private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1202 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1203 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1204}
1205
Harald Weltef7191672019-05-02 20:37:23 +02001206private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
1207 [] BSSGP[gb_idx].receive(tr_BD_LLC(tr_LLC_XID_MT_CMD(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001208 repeat;
1209 }
1210}
1211
1212template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1213 pDU_SN_UNITDATA := {
1214 nsapi := nsapi,
1215 moreBit := ?,
1216 snPduType := '1'B,
1217 firstSegmentIndicator := ?,
1218 spareBit := ?,
1219 pcomp := ?,
1220 dcomp := ?,
1221 npduNumber := ?,
1222 segmentNumber := ?,
1223 npduNumberContinued := ?,
1224 dataSegmentSnUnitdataPdu := payload
1225 }
1226}
1227
1228/* simple case: single segment, no compression */
1229template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1230 pDU_SN_UNITDATA := {
1231 nsapi := nsapi,
1232 moreBit := '0'B,
1233 snPduType := '1'B,
1234 firstSegmentIndicator := '1'B,
1235 spareBit := '0'B,
1236 pcomp := '0000'B,
1237 dcomp := '0000'B,
1238 npduNumber := '0000'B,
1239 segmentNumber := '0000'B,
1240 npduNumberContinued := '00'O,
1241 dataSegmentSnUnitdataPdu := payload
1242 }
1243}
1244
1245/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001246private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1247runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001248 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1249 f_gtpu_send(apars, payload);
1250 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1251 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001252 [] as_xid(apars, gb_idx);
1253 [] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001254 }
1255}
1256
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001257/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001258private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1259runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001260 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1261 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1262 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001263 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001264 /* Expect PDU via GTP from SGSN on simulated GGSN */
1265 alt {
1266 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1267 }
1268}
1269
Harald Welteeded9ad2018-02-17 20:57:34 +01001270private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001271 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001272
1273 /* first perform regular attach */
1274 f_TC_attach(id);
1275
1276 f_pdp_ctx_act(apars);
1277}
1278testcase TC_attach_pdp_act() runs on test_CT {
1279 var BSSGP_ConnHdlr vc_conn;
1280 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001281 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001282 vc_conn.done;
1283}
Harald Welteb2124b22018-02-16 22:26:56 +01001284
Harald Welte835b15f2018-02-18 14:39:11 +01001285/* PDP Context activation for not-attached subscriber; expect fail */
1286private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001287 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001288 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 +01001289 apars.apn, apars.pco));
1290 alt {
1291 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001292 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001293 setverdict(pass);
1294 }
1295 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1296 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001297 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001298 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001299 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001300 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001301 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001302 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001303 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001304 }
1305}
1306testcase TC_pdp_act_unattached() runs on test_CT {
1307 var BSSGP_ConnHdlr vc_conn;
1308 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001309 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001310 vc_conn.done;
1311}
1312
Harald Welte37692d82018-02-18 15:21:34 +01001313/* ATTACH + PDP CTX ACT + user plane traffic */
1314private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1315 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1316
1317 /* first perform regular attach */
1318 f_TC_attach(id);
1319 /* then activate PDP context */
1320 f_pdp_ctx_act(apars);
1321 /* then transceive a downlink PDU */
1322 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1323 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1324}
1325testcase TC_attach_pdp_act_user() runs on test_CT {
1326 var BSSGP_ConnHdlr vc_conn;
1327 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001328 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001329 vc_conn.done;
1330}
1331
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001332/* ATTACH + PDP CTX ACT; reject from GGSN */
1333private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1334 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1335
1336 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1337 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1338
1339 /* first perform regular attach */
1340 f_TC_attach(id);
1341 /* then activate PDP context */
1342 f_pdp_ctx_act(apars);
1343}
1344testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1345 var BSSGP_ConnHdlr vc_conn;
1346 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001347 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001348 vc_conn.done;
1349}
Harald Welte835b15f2018-02-18 14:39:11 +01001350
Harald Welte6f203162018-02-18 22:04:55 +01001351/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1352private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1353 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1354
1355 /* first perform regular attach */
1356 f_TC_attach(id);
1357 /* then activate PDP context */
1358 f_pdp_ctx_act(apars);
1359 /* then transceive a downlink PDU */
1360 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1361 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1362
1363 f_pdp_ctx_deact_mo(apars, '00'O);
1364}
1365testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1366 var BSSGP_ConnHdlr vc_conn;
1367 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001368 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 +01001369 vc_conn.done;
1370}
1371
Harald Welte57b9b7f2018-02-18 22:28:13 +01001372/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1373private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1374 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1375
1376 /* first perform regular attach */
1377 f_TC_attach(id);
1378 /* then activate PDP context */
1379 f_pdp_ctx_act(apars);
1380 /* then transceive a downlink PDU */
1381 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1382 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1383
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001384 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001385}
1386testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1387 var BSSGP_ConnHdlr vc_conn;
1388 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001389 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 +01001390 vc_conn.done;
1391}
1392
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001393/* ATTACH + ATTACH (2nd) */
1394private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1395 g_pars.t_guard := 5.0;
1396
1397 /* first perform regular attach */
1398 f_TC_attach(id);
1399
1400 /* second to perform regular attach */
1401 f_TC_attach(id);
1402}
1403
1404
1405testcase TC_attach_second_attempt() runs on test_CT {
1406 var BSSGP_ConnHdlr vc_conn;
1407 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001408 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001409 vc_conn.done;
1410}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001411
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001412private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001413 var Gtp1cUnitdata g_ud;
1414 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1415
1416 /* first perform regular attach */
1417 f_TC_attach(id);
1418 /* Activate a pdp context against the GGSN */
1419 f_pdp_ctx_act(apars);
1420 /* Wait to receive first echo request and send initial Restart counter */
1421 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1422 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1423 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1424 }
1425 /* Wait to receive second echo request and send incremented Restart
1426 counter. This will fake a restarted GGSN, and pdp ctx allocated
1427 should be released by SGSN */
1428 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1429 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1430 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1431 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1432 }
1433 var OCT1 cause_network_failure := int2oct(38, 1)
1434 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001435 [] 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 +02001436 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001437 setverdict(pass);
1438 }
1439 [] as_xid(apars);
1440 }
1441 setverdict(pass);
1442}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001443/* ATTACH + trigger Recovery procedure through EchoResp */
1444testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001445 var BSSGP_ConnHdlr vc_conn;
1446 g_use_echo := true
1447 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001448 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 +02001449 vc_conn.done;
1450 g_use_echo := false
1451}
1452
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001453private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1454 var Gtp1cUnitdata g_ud;
1455 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1456 var integer seq_nr := 23;
1457 var GtpPeer peer;
1458 /* first perform regular attach */
1459 f_TC_attach(id);
1460
1461 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1462 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1463 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1464 f_pdp_ctx_act(apars, true);
1465
1466 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1467/* received. */
1468 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1469
1470 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1471 would be great to have an active pdp context here before triggering
1472 Recovery, and making sure the the DEACT request is sent by the SGSN.
1473 */
1474
1475 /* Activate a pdp context against the GGSN, send incremented Recovery
1476 IE. This should trigger the recovery path, but still this specific
1477 CTX activation should work. */
1478 apars.exp_rej_cause := omit; /* default value for tests */
1479 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1480 f_pdp_ctx_act(apars, true);
1481
1482 setverdict(pass);
1483}
1484/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1485testcase TC_attach_restart_ctr_create() runs on test_CT {
1486 var BSSGP_ConnHdlr vc_conn;
1487 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001488 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 +02001489 vc_conn.done;
1490}
1491
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001492/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1493private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1494 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1495 var integer seq_nr := 23;
1496 var GtpPeer peer;
1497 var integer i;
1498
1499 /* first perform regular attach */
1500 f_TC_attach(id);
1501 /* then activate PDP context */
1502 f_pdp_ctx_act(apars);
1503
Alexander Couzens0e510e62018-07-28 23:06:00 +02001504 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001505 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1506 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1507
1508 for (i := 0; i < 5; i := i+1) {
1509 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001510 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001511 [] as_xid(apars);
1512 }
1513 }
1514
1515 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1516
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001517 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001518 setverdict(pass);
1519}
1520testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1521 var BSSGP_ConnHdlr vc_conn;
1522 f_init();
1523 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001524 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 +02001525 vc_conn.done;
1526}
1527
Alexander Couzens5e307b42018-05-22 18:12:20 +02001528private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1529 /* MS: perform regular attach */
1530 f_TC_attach(id);
1531
1532 /* HLR: cancel the location request */
1533 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1534 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001535
1536 /* ensure no Detach Request got received */
1537 timer T := 5.0;
1538 T.start;
1539 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001540 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001541 T.stop;
1542 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001543 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001544 }
1545 [] T.timeout {
1546 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001547 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001548 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001549 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001550 repeat;
1551 }
1552 }
1553}
1554
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001555/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1556private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1557 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1558
1559 /* first perform regular attach */
1560 f_TC_attach(id);
1561 /* then activate PDP context */
1562 f_pdp_ctx_act(apars);
1563 /* then transceive a downlink PDU */
1564 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1565
1566 /* Send Error indication as response from upload PDU and expect deact towards MS */
1567 f_pdp_ctx_deact_mt(apars, true);
1568}
1569testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1570 var BSSGP_ConnHdlr vc_conn;
1571 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001572 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 +02001573 vc_conn.done;
1574}
1575
Alexander Couzens5e307b42018-05-22 18:12:20 +02001576testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1577 /* MS <-> SGSN: GMM Attach
1578 * HLR -> SGSN: Cancel Location Request
1579 * HLR <- SGSN: Cancel Location Ack
1580 */
1581 var BSSGP_ConnHdlr vc_conn;
1582 f_init();
1583 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001584 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001585 vc_conn.done;
1586}
1587
1588
Alexander Couzensc87967a2018-05-22 16:09:54 +02001589private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1590 /* MS: perform regular attach */
1591 f_TC_attach(id);
1592
1593 /* HLR: cancel the location request */
1594 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1595 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1596 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1597
1598 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001599 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 +02001600 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001601
1602 setverdict(pass);
1603}
1604
1605testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1606 /* MS <-> SGSN: GMM Attach
1607 * HLR -> SGSN: Cancel Location Request
1608 * HLR <- SGSN: Cancel Location Ack
1609 * MS <- SGSN: Detach Request
1610 * SGSN-> MS: Detach Complete
1611 */
1612 var BSSGP_ConnHdlr vc_conn;
1613 f_init();
1614 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001615 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001616 vc_conn.done;
1617}
1618
1619
Alexander Couzens6c47f292018-05-22 17:09:49 +02001620private function f_hlr_location_cancel_request_unknown_subscriber(
1621 charstring id,
1622 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1623
1624 /* HLR: cancel the location request */
1625 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1626
1627 /* cause 2 = IMSI_UNKNOWN */
1628 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1629
1630 setverdict(pass);
1631}
1632
1633private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001634 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001635}
1636
1637testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1638 /* HLR -> SGSN: Cancel Location Request
1639 * HLR <- SGSN: Cancel Location Error
1640 */
1641
1642 var BSSGP_ConnHdlr vc_conn;
1643 f_init();
1644 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001645 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 +02001646 vc_conn.done;
1647}
1648
1649private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001650 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001651}
1652
1653testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1654 /* HLR -> SGSN: Cancel Location Request
1655 * HLR <- SGSN: Cancel Location Error
1656 */
1657
1658 var BSSGP_ConnHdlr vc_conn;
1659 f_init();
1660 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001661 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 +02001662 vc_conn.done;
1663}
1664
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001665private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1666 f_TC_attach(id);
1667 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1668}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001669
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001670testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1671 /* MS <-> SGSN: Attach
1672 * MS -> SGSN: Detach Req (Power off)
1673 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1674 */
1675 var BSSGP_ConnHdlr vc_conn;
1676 var integer id := 33;
1677 var charstring imsi := hex2str(f_gen_imsi(id));
1678
1679 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001680 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001681 vc_conn.done;
1682
1683 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1684}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001685
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001686/* Attempt an attach, but loose the Identification Request (IMEI) */
1687private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1688 var integer count_req := 0;
1689 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1690
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001691 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 +02001692
1693 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001694 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001695 /* break */
1696 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001697 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001698 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001699 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001700 repeat;
1701 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001702 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001703 /* ignore ID REQ IMEI */
1704 count_req := count_req + 1;
1705 repeat;
1706 }
1707 }
1708 if (count_req != 5) {
1709 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001710 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001711 }
1712 setverdict(pass);
1713}
1714
1715testcase TC_attach_no_imei_response() runs on test_CT {
1716 /* MS -> SGSN: Attach Request IMSI
1717 * MS <- SGSN: Identity Request IMSI (optional)
1718 * MS -> SGSN: Identity Response IMSI (optional)
1719 * MS <- SGSN: Identity Request IMEI
1720 * MS -x SGSN: no response
1721 * MS <- SGSN: re-send: Identity Request IMEI 4x
1722 * MS <- SGSN: Attach Reject
1723 */
1724 var BSSGP_ConnHdlr vc_conn;
1725 f_init();
1726 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001727 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 +02001728 vc_conn.done;
1729}
1730
Alexander Couzens53f20562018-06-12 16:24:12 +02001731/* Attempt an attach, but loose the Identification Request (IMSI) */
1732private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1733 var integer count_req := 0;
1734 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1735
1736 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1737 g_pars.p_tmsi := 'c0000035'O;
1738
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001739 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 +02001740
1741 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001742 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001743 /* break */
1744 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001745 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001746 /* ignore ID REQ IMSI */
1747 count_req := count_req + 1;
1748 repeat;
1749 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001750 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001751 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001752 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001753 repeat;
1754 }
1755 }
1756 if (count_req != 5) {
1757 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001758 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001759 }
1760 setverdict(pass);
1761}
1762
1763testcase TC_attach_no_imsi_response() runs on test_CT {
1764 /* MS -> SGSN: Attach Request TMSI (unknown)
1765 * MS <- SGSN: Identity Request IMEI (optional)
1766 * MS -> SGSN: Identity Response IMEI (optional)
1767 * MS <- SGSN: Identity Request IMSI
1768 * MS -x SGSN: no response
1769 * MS <- SGSN: re-send: Identity Request IMSI 4x
1770 * MS <- SGSN: Attach Reject
1771 */
1772 var BSSGP_ConnHdlr vc_conn;
1773 f_init();
1774 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001775 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 +02001776 vc_conn.done;
1777}
1778
Alexander Couzenscf818962018-06-05 18:00:00 +02001779private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1780 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1781}
1782
1783testcase TC_attach_check_subscriber_list() runs on test_CT {
1784 /* MS <-> SGSN: Attach
1785 * VTY -> SGSN: Check if MS is in subscriber cache
1786 */
1787 var BSSGP_ConnHdlr vc_conn;
1788 var integer id := 34;
1789 var charstring imsi := hex2str(f_gen_imsi(id));
1790
1791 f_init();
1792 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001793 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001794 vc_conn.done;
1795
1796 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1797 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1798}
1799
Alexander Couzensf9858652018-06-07 16:14:53 +02001800private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1801 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1802 var BssgpDecoded bd;
1803
1804 /* unregister the old IMSI */
1805 f_bssgp_client_unregister(g_pars.imsi);
1806 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001807 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001808 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001809
1810 /* there is no auth */
1811 g_pars.net.expect_auth := false;
1812
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001813 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 +02001814 f_gmm_auth();
1815 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001816 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001817 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001818 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001819 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001820 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001821 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001822 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001823 setverdict(pass);
1824 }
1825 }
1826}
Alexander Couzens03d12242018-08-07 16:13:52 +02001827
1828private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1829
1830 f_TC_attach_closed_foreign(id);
1831 f_TC_attach_closed_imsi_added(id);
1832
1833}
1834
1835
Alexander Couzensf9858652018-06-07 16:14:53 +02001836testcase TC_attach_closed_add_vty() runs on test_CT {
1837 /* VTY-> SGSN: policy close
1838 * MS -> SGSN: Attach Request
1839 * MS <- SGSN: Identity Request IMSI
1840 * MS -> SGSN: Identity Response IMSI
1841 * MS <- SGSN: Attach Reject
1842 * VTY-> SGSN: policy imsi-acl add IMSI
1843 * MS -> SGSN: Attach Request
1844 * MS <- SGSN: Identity Request IMSI
1845 * MS -> SGSN: Identity Response IMSI
1846 * MS <- SGSN: Identity Request IMEI
1847 * MS -> SGSN: Identity Response IMEI
1848 * MS <- SGSN: Attach Accept
1849 */
1850 var BSSGP_ConnHdlr vc_conn;
1851 f_init();
1852 f_sleep(1.0);
1853 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1854 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001855 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1856 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001857 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001858 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001859 vc_conn.done;
1860}
1861
Alexander Couzens0085bd72018-06-12 19:08:44 +02001862/* Attempt an attach, but never answer a Attach Complete */
1863private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1864 var integer count_req := 0;
1865
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001866 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 +02001867 f_gmm_auth();
1868
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001869 timer T := 10.0;
1870 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001871 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001872 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001873 /* break */
1874 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001875 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001876 /* ignore */
1877 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001878 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001879 repeat;
1880 }
1881 }
1882 if (count_req != 5) {
1883 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001884 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001885 }
1886 setverdict(pass);
1887}
1888
1889testcase TC_attach_check_complete_resend() runs on test_CT {
1890 /* MS -> SGSN: Attach Request IMSI
1891 * MS <- SGSN: Identity Request *
1892 * MS -> SGSN: Identity Response *
1893 * MS <- SGSN: Attach Complete 5x
1894 */
1895 var BSSGP_ConnHdlr vc_conn;
1896 f_init();
1897 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001898 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 +02001899 vc_conn.done;
1900}
1901
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001902private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
1903 var BssgpDecoded bd;
1904
1905 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001906 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 +02001907 alt {
1908 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001909 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001910 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001911 setverdict(pass);
1912 }
1913 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
1914 setverdict(fail, "Unexpected RAU Reject");
1915 mtc.stop;
1916 }
1917 [] BSSGP[bssgp].receive { repeat; }
1918 }
1919}
1920
Alexander Couzensbfda9212018-07-31 03:17:33 +02001921private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
1922 var BssgpDecoded bd;
1923
1924 /* first perform regular attach */
1925 f_TC_attach(id);
1926
1927 /* then send RAU */
1928 f_routing_area_update(g_pars.ra);
1929
1930 /* do another RAU */
1931 f_routing_area_update(g_pars.ra);
1932
1933 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1934}
1935
1936testcase TC_attach_rau_a_a() runs on test_CT {
1937 /* MS <-> SGSN: Successful Attach
1938 * MS -> SGSN: Routing Area Update Request
1939 * MS <- SGSN: Routing Area Update Accept
1940 * MS -> SGSN: Routing Area Update Request
1941 * MS <- SGSN: Routing Area Update Accept
1942 * MS -> SGSN: Detach (PowerOff)
1943 */
1944 var BSSGP_ConnHdlr vc_conn;
1945 f_init();
1946 f_sleep(1.0);
1947 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
1948 vc_conn.done;
1949}
1950
Alexander Couzensbe837bd2018-07-31 04:20:11 +02001951private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
1952 var BssgpDecoded bd;
1953
1954 f_TC_attach(id);
1955
1956 log("attach complete sending rau");
1957 f_routing_area_update(g_pars.ra, 0);
1958
1959 log("rau complete unregistering");
1960 f_bssgp_client_unregister(g_pars.imsi);
1961 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
1962
1963 log("sending second RAU via different RA");
1964 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
1965
1966 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
1967}
1968
1969testcase TC_attach_rau_a_b() runs on test_CT {
1970 /* MS <-> SGSN: Successful Attach
1971 * MS -> SGSN: Routing Area _a_ Update Request
1972 * MS <- SGSN: Routing Area _a_ Update Accept
1973 * MS -> SGSN: Routing Area _b_ Update Request
1974 * MS <- SGSN: Routing Area _b_ Update Accept
1975 * MS -> SGSN: Detach (PowerOff)
1976 */
1977 var BSSGP_ConnHdlr vc_conn;
1978 f_init();
1979 f_sleep(1.0);
1980 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
1981 vc_conn.done;
1982}
1983
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02001984private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
1985 var integer count_req := 0;
1986 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1987 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
1988 var BssgpDecoded bd;
1989
1990 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1991
1992 alt {
1993 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1994 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1995 mtc.stop;
1996 }
1997 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1998 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1999 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2000 repeat;
2001 }
2002 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2003 /* send out a second GMM_Attach Request.
2004 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2005 * of the same content */
2006 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2007 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
2008 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2009 }
2010 }
2011 f_sleep(1.0);
2012
2013 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2014 alt {
2015 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2016 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2017 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2018 repeat;
2019 }
2020 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2021 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2022 mtc.stop;
2023 }
2024 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2025 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2026 mtc.stop;
2027 }
2028 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2029 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2030 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2031 setverdict(pass);
2032 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2033 }
2034 }
2035}
2036
2037testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2038 /* Testing if the SGSN ignore Attach Request with the exact same content */
2039 /* MS -> SGSN: Attach Request IMSI
2040 * MS <- SGSN: Identity Request IMSI (optional)
2041 * MS -> SGSN: Identity Response IMSI (optional)
2042 * MS <- SGSN: Identity Request IMEI
2043 * MS -> SGSN: Attach Request (2nd)
2044 * MS <- SGSN: Identity Response IMEI
2045 * MS <- SGSN: Attach Accept
2046 * MS -> SGSN: Attach Complete
2047 */
2048 var BSSGP_ConnHdlr vc_conn;
2049 f_init();
2050 f_sleep(1.0);
2051 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2052 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2053 vc_conn.done;
2054}
2055
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002056private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
2057 var BssgpDecoded bd;
2058 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2059
2060 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2061
2062 /* send Attach Request */
2063 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2064 * 3G auth vectors */
2065 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2066 /* The thing is, if the solSACapability is 'omit', then the
2067 * revisionLevelIndicatior is at the wrong place! */
2068 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2069 f_send_l3_gmm_llc(attach_req);
2070
2071 /* do the auth */
2072 var PDU_L3_MS_SGSN l3_mo;
2073 var PDU_L3_SGSN_MS l3_mt;
2074 var default di := activate(as_mm_identity());
2075
2076 var GSUP_IE auth_tuple;
2077 var template AuthenticationParameterAUTNTLV autn;
2078
2079 g_pars.vec := f_gen_auth_vec_3g();
2080 autn := {
2081 elementIdentifier := '28'O,
2082 lengthIndicator := lengthof(g_pars.vec.autn),
2083 autnValue := g_pars.vec.autn
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 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2093 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2094 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2095
2096 var template PDU_L3_SGSN_MS 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
2100 /* send the gmm auth failure with resync IE */
2101 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2102
2103 /* wait for the GSUP resync request */
2104 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2105 g_pars.imsi,
2106 g_pars.vec.auts,
2107 g_pars.vec.rand));
2108
2109 /* generate new key material */
2110 g_pars.vec := f_gen_auth_vec_3g();
2111 autn := {
2112 elementIdentifier := '28'O,
2113 lengthIndicator := lengthof(g_pars.vec.autn),
2114 autnValue := g_pars.vec.autn
2115 };
2116
2117 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2118 g_pars.vec.sres,
2119 g_pars.vec.kc,
2120 g_pars.vec.ik,
2121 g_pars.vec.ck,
2122 g_pars.vec.autn,
2123 g_pars.vec.res));
2124 /* send new key material */
2125 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2126
2127 /* wait for the new Auth Request */
2128 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2129 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2130 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2131 l3_mt := bd.l3_mt;
2132 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2133 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2134 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2135 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2136 valueField := substr(g_pars.vec.res, 0, 4)
2137 };
2138 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2139 elementIdentifier := '21'O,
2140 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2141 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2142 };
2143 l3_mo := valueof(auth_ciph_resp);
2144 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2145 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2146 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2147 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2148 }
2149 f_send_l3_gmm_llc(l3_mo);
2150 deactivate(di);
2151
2152 /* Expect SGSN to perform LU with HLR */
2153 f_gmm_gsup_lu_isd();
2154
2155 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2156 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2157 }
2158 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2159 setverdict(pass);
2160}
2161
2162testcase TC_attach_usim_resync() runs on test_CT {
2163 /* MS -> SGSN: Attach Request
2164 * MS <- SGSN: Identity Request IMSI
2165 * MS -> SGSN: Identity Response IMSI
2166 * MS <- SGSN: Identity Request IMEI
2167 * MS -> SGSN: Identity Response IMEI
2168 * HLR<- SGSN: SAI Request
2169 * HLR-> SGSN: SAI Response
2170 * MS <- SGSN: Auth Request
2171 * MS -> SGSN: Auth Failure (with AUTS)
2172 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2173 * HLR-> SGSN: SAI Response (new key material)
2174 * MS <- SGSN: Auth Request (new key material)
2175 * MS -> SGSN: Auth Response
2176 * MS <- SGSN: Attach Accept
2177 * MS -> SGSN: Attach Complete
2178 */
2179 var BSSGP_ConnHdlr vc_conn;
2180 f_init();
2181 f_sleep(1.0);
2182 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2183 vc_conn.done;
2184}
2185
Harald Weltea05b8072019-04-23 22:35:05 +02002186
2187/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2188private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2189 f_gmm_attach(false, false);
2190 f_sleep(1.0);
2191 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2192 /* try to detach to check if SGSN is still alive */
2193 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2194}
2195testcase TC_llc_null() runs on test_CT {
2196 var BSSGP_ConnHdlr vc_conn;
2197 f_init();
2198 f_sleep(1.0);
2199 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2200 vc_conn.done;
2201}
2202
Harald Welte645a1512019-04-23 23:18:23 +02002203/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2204private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2205 f_gmm_attach(false, false);
2206 f_sleep(1.0);
2207 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2208 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP)));
2209 setverdict(pass);
2210}
2211testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2212 var BSSGP_ConnHdlr vc_conn;
2213 f_init();
2214 f_sleep(1.0);
2215 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2216 vc_conn.done;
2217}
2218
2219/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2220private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2221 f_gmm_attach(false, false);
2222 f_sleep(1.0);
2223 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
2224 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP)));
2225 setverdict(pass);
2226}
2227testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2228 var BSSGP_ConnHdlr vc_conn;
2229 f_init();
2230 f_sleep(1.0);
2231 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2232 vc_conn.done;
2233}
2234
Harald Welte2aaac1b2019-05-02 10:02:53 +02002235/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2236private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2237 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2238 var template (value) XID_Information xid;
2239 var template XID_Information xid_rx;
2240
2241 /* first perform regular attach */
2242 f_TC_attach(id);
2243 /* then activate PDP context */
2244 f_pdp_ctx_act(apars);
2245
2246 /* start MO XID */
2247 xid := { ts_XID_L3(''O) };
2248 xid_rx := { tr_XID_L3(''O) };
2249 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2250 alt {
2251 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(xid_rx, apars.sapi)));
2252 [] as_xid(apars);
2253 }
2254 setverdict(pass);
2255}
2256testcase TC_xid_empty_l3() runs on test_CT {
2257 var BSSGP_ConnHdlr vc_conn;
2258 f_init();
2259 f_sleep(1.0);
2260 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2261 vc_conn.done;
2262}
2263
2264private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2265 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2266 var template (value) XID_Information xid;
2267 var template XID_Information xid_rx;
2268
2269 /* first perform regular attach */
2270 f_TC_attach(id);
2271 /* then activate PDP context */
2272 f_pdp_ctx_act(apars);
2273
2274 /* start MO XID */
2275 xid := { ts_XID_N201U(1234) };
2276 xid_rx := { tr_XID_N201U(1234) };
2277 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2278 alt {
2279 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi)));
2280 [] as_xid(apars);
2281 }
2282 setverdict(pass);
2283}
2284testcase TC_xid_n201u() runs on test_CT {
2285 var BSSGP_ConnHdlr vc_conn;
2286 f_init();
2287 f_sleep(1.0);
2288 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2289 vc_conn.done;
2290}
2291
Alexander Couzens6bee0872019-05-11 01:48:50 +02002292private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2293 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2294
2295 /* first perform regular attach */
2296 f_TC_attach(id);
2297 /* then activate PDP context */
2298 f_pdp_ctx_act(apars);
2299 /* do a normal detach */
2300 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2301}
2302
2303testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2304 /* MS -> SGSN: Attach Request
2305 * MS <-> SGSN: [..]
2306 * MS -> SGSN: Attach Complete
2307 * MS -> SGSN: PDP Activate Request
2308 * MS <- SGSN: PDP Activate Accept
2309 * MS -> SGSN: GMM Detach Request
2310 * MS <- SGSN: GMM Detach Accept
2311 */
2312 var BSSGP_ConnHdlr vc_conn;
2313 f_init();
2314 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2315 vc_conn.done;
2316}
Harald Welte645a1512019-04-23 23:18:23 +02002317
2318
Harald Welte5ac31492018-02-15 20:39:13 +01002319control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002320 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002321 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002322 execute( TC_attach_umts_aka_umts_res() );
2323 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002324 execute( TC_attach_auth_id_timeout() );
2325 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002326 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002327 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002328 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002329 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002330 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002331 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002332 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002333 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002334 execute( TC_attach_closed_add_vty(), 20.0 );
2335 execute( TC_attach_check_subscriber_list(), 20.0 );
2336 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002337 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002338 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2339 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2340 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2341 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002342 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002343 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002344 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002345 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002346 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002347 execute( TC_detach_unknown_nopoweroff() );
2348 execute( TC_detach_unknown_poweroff() );
2349 execute( TC_detach_nopoweroff() );
2350 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002351 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002352 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002353 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002354 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002355 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002356 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002357 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002358 execute( TC_attach_restart_ctr_echo() );
2359 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002360 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002361 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002362 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002363 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002364
Harald Welte2aaac1b2019-05-02 10:02:53 +02002365 execute( TC_xid_empty_l3() );
2366 execute( TC_xid_n201u() );
2367
Harald Weltea05b8072019-04-23 22:35:05 +02002368 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002369 execute( TC_llc_sabm_dm_llgmm() );
2370 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002371}
Harald Welte96a33b02018-02-04 10:36:22 +01002372
2373
2374
2375}