blob: 0112483f8cd4af298c6d5ba863d3fa347468c1df [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,
54 nsei := 96
55 },
56 {
57 local_udp_port := 21011,
58 local_ip := "127.0.0.1",
59 remote_udp_port := 23000,
60 remote_ip := "127.0.0.1",
61 nsvci := 98,
62 nsei := 97
63 },
64 {
65 local_udp_port := 21012,
66 local_ip := "127.0.0.1",
67 remote_udp_port := 23000,
68 remote_ip := "127.0.0.1",
69 nsvci := 99,
70 nsei := 98
71 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020072 };
Harald Welte5ac31492018-02-15 20:39:13 +010073};
74
75type record GbInstance {
76 NS_CT vc_NS,
77 BSSGP_CT vc_BSSGP,
78 BssgpConfig cfg
79};
Harald Welte96a33b02018-02-04 10:36:22 +010080
Alexander Couzens51114d12018-07-31 18:41:56 +020081type record length(3) of GbInstance GbInstances;
Alexander Couzensf3c1b412018-08-24 00:42:51 +020082type record length(3) of NSConfiguration NSConfigurations;
Alexander Couzens51114d12018-07-31 18:41:56 +020083type record length(3) of BssgpCellId BssgpCellIds;
84
Harald Welte96a33b02018-02-04 10:36:22 +010085type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +020086 var GbInstances g_gb;
Harald Welte96a33b02018-02-04 10:36:22 +010087
Harald Welte5ac31492018-02-15 20:39:13 +010088 var GSUP_Emulation_CT vc_GSUP;
89 var IPA_Emulation_CT vc_GSUP_IPA;
90 /* only to get events from IPA underneath GSUP */
91 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010092
Harald Welteeded9ad2018-02-17 20:57:34 +010093 var GTP_Emulation_CT vc_GTP;
94
Harald Weltebd194722018-02-16 22:11:08 +010095 port TELNETasp_PT SGSNVTY;
96
Harald Welte96a33b02018-02-04 10:36:22 +010097 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +020098 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +010099};
100
Harald Welteeded9ad2018-02-17 20:57:34 +0100101type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100102 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100103 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200104 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100105}
106
107type record SGSN_ConnHdlrNetworkPars {
108 boolean expect_ptmsi,
109 boolean expect_auth,
110 boolean expect_ciph
111};
112
113type record BSSGP_ConnHdlrPars {
114 /* IMEI of the simulated ME */
115 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200116 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100117 hexstring imsi,
118 /* MSISDN of the simulated MS (probably unused) */
119 hexstring msisdn,
120 /* P-TMSI allocated to the simulated MS */
121 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100122 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100123 /* TLLI of the simulated MS */
124 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100125 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100126 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200127 BssgpCellIds bssgp_cell_id,
Harald Welte5ac31492018-02-15 20:39:13 +0100128 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100129 SGSN_ConnHdlrNetworkPars net,
130 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100131};
132
Alexander Couzens89508702018-07-31 04:16:10 +0200133private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
134 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
135
136 var RoutingAreaIdentificationV ret := {
137 mccDigit1 := mcc_mnc[0],
138 mccDigit2 := mcc_mnc[1],
139 mccDigit3 := mcc_mnc[2],
140 mncDigit3 := mcc_mnc[5],
141 mncDigit1 := mcc_mnc[3],
142 mncDigit2 := mcc_mnc[4],
143 lac := int2oct(cell_id.ra_id.lai.lac, 16),
144 rac := int2oct(cell_id.ra_id.rac, 8)
145 }
146 return ret;
147};
148
Alexander Couzens51114d12018-07-31 18:41:56 +0200149private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
150 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
151 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100152 /* connect lower end of BSSGP emulation with NS upper port */
153 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
154 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
155 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
156
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200157 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100158 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
159}
160
161private function f_init_gsup(charstring id) runs on test_CT {
162 id := id & "-GSUP";
163 var GsupOps ops := {
164 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
165 };
166
167 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
168 vc_GSUP := GSUP_Emulation_CT.create(id);
169
170 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
171 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
172 /* we use this hack to get events like ASP_IPA_EVENT_UP */
173 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
174
175 vc_GSUP.start(GSUP_Emulation.main(ops, id));
176 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
177
178 /* wait for incoming connection to GSUP port before proceeding */
179 timer T := 10.0;
180 T.start;
181 alt {
182 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
183 [] T.timeout {
184 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200185 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100186 }
187 }
188}
189
Harald Welteeded9ad2018-02-17 20:57:34 +0100190private function f_init_gtp(charstring id) runs on test_CT {
191 id := id & "-GTP";
192
193 var GtpEmulationCfg gtp_cfg := {
194 gtpc_bind_ip := mp_ggsn_ip,
195 gtpc_bind_port := GTP1C_PORT,
196 gtpu_bind_ip := mp_ggsn_ip,
197 gtpu_bind_port := GTP1U_PORT,
198 sgsn_role := false
199 };
200
201 vc_GTP := GTP_Emulation_CT.create(id);
202 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
203}
204
Harald Weltebd194722018-02-16 22:11:08 +0100205private function f_init_vty() runs on test_CT {
206 map(self:SGSNVTY, system:SGSNVTY);
207 f_vty_set_prompts(SGSNVTY);
208 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200209 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100210 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
211}
212
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200213private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
214 if (enable) {
215 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
216 } else {
217 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
218 }
219}
220
Harald Weltebd194722018-02-16 22:11:08 +0100221
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100222function f_init(BcdMccMnc mcc_mnc := '26242F'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100223 if (g_initialized == true) {
224 return;
225 }
226 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100227 g_gb[0].cfg := {
228 nsei := 96,
229 bvci := 196,
230 cell_id := {
231 ra_id := {
232 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100233 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100234 rac := 0
235 },
236 cell_id := 20960
237 },
238 sgsn_role := false
239 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200240 g_gb[1].cfg := {
241 nsei := 97,
242 bvci := 210,
243 cell_id := {
244 ra_id := {
245 lai := {
246 mcc_mnc := mcc_mnc, lac := 13200},
247 rac := 0
248 },
249 cell_id := 20961
250 },
251 sgsn_role := false
252 };
253 g_gb[2].cfg := {
254 nsei := 98,
255 bvci := 220,
256 cell_id := {
257 ra_id := {
258 lai := {
259 mcc_mnc := mcc_mnc, lac := 13300},
260 rac := 0
261 },
262 cell_id := 20962
263 },
264 sgsn_role := false
265 };
Harald Welte96a33b02018-02-04 10:36:22 +0100266
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200267 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200268 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
269 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
270 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte5ac31492018-02-15 20:39:13 +0100271 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100272 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200273 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100274}
Harald Welte96a33b02018-02-04 10:36:22 +0100275
Harald Welte5ac31492018-02-15 20:39:13 +0100276type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
277
278/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200279function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100280 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100281runs on test_CT return BSSGP_ConnHdlr {
282 var BSSGP_ConnHdlr vc_conn;
283 var SGSN_ConnHdlrNetworkPars net_pars := {
284 expect_ptmsi := true,
285 expect_auth := true,
286 expect_ciph := false
287 };
288 var BSSGP_ConnHdlrPars pars := {
289 imei := f_gen_imei(imsi_suffix),
290 imsi := f_gen_imsi(imsi_suffix),
291 msisdn := f_gen_msisdn(imsi_suffix),
292 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100293 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100294 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100295 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100296 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200297 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 +0100298 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100299 net := net_pars,
300 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100301 };
302
303 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200304 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
305 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
306 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
307 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
308 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
309 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100310
311 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
312 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
313
Harald Welteeded9ad2018-02-17 20:57:34 +0100314 connect(vc_conn:GTP, vc_GTP:CLIENT);
315 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
316
Harald Welte5ac31492018-02-15 20:39:13 +0100317 vc_conn.start(f_handler_init(fn, id, pars));
318 return vc_conn;
319}
320
Harald Welte62e29582018-02-16 21:17:11 +0100321private altstep as_Tguard() runs on BSSGP_ConnHdlr {
322 [] g_Tguard.timeout {
323 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200324 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100325 }
326}
327
Harald Welte5ac31492018-02-15 20:39:13 +0100328/* first function called in every ConnHdlr */
329private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
330runs on BSSGP_ConnHdlr {
331 /* do some common stuff like setting up g_pars */
332 g_pars := pars;
333
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200334 llc := f_llc_create(false);
335
Harald Welte5ac31492018-02-15 20:39:13 +0100336 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200337 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100338 /* tell GSUP dispatcher to send this IMSI to us */
339 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100340 /* tell GTP dispatcher to send this IMSI to us */
341 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100342
Harald Welte62e29582018-02-16 21:17:11 +0100343 g_Tguard.start(pars.t_guard);
344 activate(as_Tguard());
345
Harald Welte5ac31492018-02-15 20:39:13 +0100346 /* call the user-supplied test case function */
347 fn.apply(id);
348 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100349}
350
351/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100352 * Detach without Attach
353 * SM procedures without attach / RAU
354 * ATTACH / RAU
355 ** with / without authentication
356 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100357 * re-transmissions of LLC frames
358 * PDP Context activation
359 ** with different GGSN config in SGSN VTY
360 ** with different PDP context type (v4/v6/v46)
361 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100362 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100363 */
364
365testcase TC_wait_ns_up() runs on test_CT {
366 f_init();
367 f_sleep(20.0);
368}
369
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200370function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
371 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
372 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
373 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
374 var octetstring llc_enc := enc_PDU_LLC(valueof(ts_LLC_UI(l3_enc, sapi, '0'B, n_u)));
375 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
376}
377
Harald Welte5ac31492018-02-15 20:39:13 +0100378altstep as_mm_identity() runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100379 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200380 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100381 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200382 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100383 repeat;
384 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200385 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100386 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200387 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100388 repeat;
389 }
390}
Harald Welte96a33b02018-02-04 10:36:22 +0100391
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200392/* perform GMM authentication (if expected).
393 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
394 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
395function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100396 var BssgpDecoded bd;
397 var PDU_L3_MS_SGSN l3_mo;
398 var PDU_L3_SGSN_MS l3_mt;
399 var default di := activate(as_mm_identity());
400 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200401 var GSUP_IE auth_tuple;
402 var template AuthenticationParameterAUTNTLV autn;
403
404 if (umts_aka_challenge) {
405 g_pars.vec := f_gen_auth_vec_3g();
406 autn := {
407 elementIdentifier := '28'O,
408 lengthIndicator := lengthof(g_pars.vec.autn),
409 autnValue := g_pars.vec.autn
410 };
411
412 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
413 g_pars.vec.sres,
414 g_pars.vec.kc,
415 g_pars.vec.ik,
416 g_pars.vec.ck,
417 g_pars.vec.autn,
418 g_pars.vec.res));
419 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
420 } else {
421 g_pars.vec := f_gen_auth_vec_2g();
422 autn := omit;
423 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
424 g_pars.vec.sres,
425 g_pars.vec.kc));
426 log("GSUP sends only 2G auth tuple", auth_tuple);
427 }
Harald Welte5ac31492018-02-15 20:39:13 +0100428 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
429 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200430
431 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
432 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200433 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
Harald Welte5ac31492018-02-15 20:39:13 +0100434 l3_mt := bd.l3_mt;
435 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200436 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
437
438 if (umts_aka_challenge and not force_gsm_sres) {
439 /* set UMTS response instead */
440 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
441 valueField := substr(g_pars.vec.res, 0, 4)
442 };
443 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
444 elementIdentifier := '21'O,
445 lengthIndicator := lengthof(g_pars.vec.res) - 4,
446 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
447 };
448 }
449
450 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100451 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
452 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
453 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
454 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
455 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200456 f_send_l3_gmm_llc(l3_mo);
Harald Welte76dee092018-02-16 22:12:59 +0100457 } else {
458 /* wait for identity procedure */
459 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100460 }
Harald Welte76dee092018-02-16 22:12:59 +0100461
Harald Welte5ac31492018-02-15 20:39:13 +0100462 deactivate(di);
463}
464
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200465function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100466 g_pars.p_tmsi := p_tmsi;
467 /* update TLLI */
468 g_pars.tlli_old := g_pars.tlli;
469 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200470 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100471}
472
Harald Welte04683d02018-02-16 22:43:45 +0100473function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
474 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100475 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200476 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100477 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200478 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200479 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100480 }
Harald Welte04683d02018-02-16 22:43:45 +0100481 g_pars.ra := aa.routingAreaIdentification;
482 if (ispresent(aa.allocatedPTMSI)) {
483 if (not g_pars.net.expect_ptmsi) {
484 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200485 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100486 }
Harald Weltef70997d2018-02-17 10:11:19 +0100487 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100488 }
489 if (ispresent(aa.msIdentity)) {
490 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200491 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100492 }
493 /* P-TMSI.sig */
494 if (ispresent(aa.ptmsiSignature)) {
495 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
496 }
497 /* updateTimer */
498 // aa.readyTimer
499 /* T3302, T3319, T3323, T3312_ext, T3324 */
500}
501
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200502function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100503 /* mandatory IE */
504 g_pars.ra := ra.routingAreaId;
505 if (ispresent(ra.allocatedPTMSI)) {
506 if (not g_pars.net.expect_ptmsi) {
507 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200508 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100509 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200510 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100511 }
512 if (ispresent(ra.msIdentity)) {
513 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200514 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100515 }
516 /* P-TMSI.sig */
517 if (ispresent(ra.ptmsiSignature)) {
518 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
519 }
520 /* updateTimer */
521 // aa.readyTimer
522 /* T3302, T3319, T3323, T3312_ext, T3324 */
523}
524
525
Harald Welte5a4fa042018-02-16 20:59:21 +0100526function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
527 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
528}
529
Harald Welte23178c52018-02-17 09:36:33 +0100530/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100531private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100532 if (ispresent(g_pars.p_tmsi)) {
533 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
534 } else {
535 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
536 }
537}
538
Harald Welte311ec272018-02-17 09:40:03 +0100539private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100540 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100541 /* Expect MSC to perform LU with HLR */
542 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100543 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
544 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
545 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100546 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
547 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
548}
549
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200550private function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100551 var BssgpDecoded bd;
Harald Welte5a4fa042018-02-16 20:59:21 +0100552 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200553 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welte5ac31492018-02-15 20:39:13 +0100554
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200555 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
556 * 3G auth vectors */
557 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
558 /* The thing is, if the solSACapability is 'omit', then the
559 * revisionLevelIndicatior is at the wrong place! */
560 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
561
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200562 f_send_l3_gmm_llc(attach_req);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200563 f_gmm_auth(umts_aka_challenge, force_gsm_sres);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200564 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100565 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100566
Alexander Couzens0e510e62018-07-28 23:06:00 +0200567 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100568 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
569 }
570 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200571 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200572}
573
574private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
575 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100576 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100577}
578
579testcase TC_attach() runs on test_CT {
580 var BSSGP_ConnHdlr vc_conn;
581 f_init();
582 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200583 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100584 vc_conn.done;
585}
586
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100587testcase TC_attach_mnc3() runs on test_CT {
588 var BSSGP_ConnHdlr vc_conn;
589 f_init('023042'H);
590 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200591 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100592 vc_conn.done;
593}
594
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200595private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
596 f_gmm_attach(true, false);
597 setverdict(pass);
598}
599testcase TC_attach_umts_aka_umts_res() runs on test_CT {
600 var BSSGP_ConnHdlr vc_conn;
601 f_init();
602 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200603 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200604 vc_conn.done;
605}
606
607private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
608 f_gmm_attach(true, true);
609 setverdict(pass);
610}
611testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
612 var BSSGP_ConnHdlr vc_conn;
613 f_init();
614 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200615 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200616 vc_conn.done;
617}
618
Harald Welte5b7c8122018-02-16 21:48:17 +0100619/* MS never responds to ID REQ, expect ATTACH REJECT */
620private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100621 var RoutingAreaIdentificationV old_ra := f_random_RAI();
622
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200623 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 +0100624 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200625 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100626 /* don't send ID Response */
627 repeat;
628 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200629 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100630 setverdict(pass);
631 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200632 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100633 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200634 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100635 }
636 }
637}
638testcase TC_attach_auth_id_timeout() runs on test_CT {
639 var BSSGP_ConnHdlr vc_conn;
640 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200641 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 +0100642 vc_conn.done;
643}
644
645/* HLR never responds to SAI REQ, expect ATTACH REJECT */
646private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100647 var RoutingAreaIdentificationV old_ra := f_random_RAI();
648
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200649 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 +0100650 alt {
651 [] as_mm_identity();
652 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
653 }
654 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200655 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100656 setverdict(pass);
657}
658testcase TC_attach_auth_sai_timeout() runs on test_CT {
659 var BSSGP_ConnHdlr vc_conn;
660 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200661 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100662 vc_conn.done;
663}
664
Harald Weltefe253882018-02-17 09:25:00 +0100665/* HLR rejects SAI, expect ATTACH REJECT */
666private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100667 var RoutingAreaIdentificationV old_ra := f_random_RAI();
668
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200669 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 +0100670 alt {
671 [] as_mm_identity();
672 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
673 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
674 }
675 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200676 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100677 setverdict(pass);
678}
679testcase TC_attach_auth_sai_reject() runs on test_CT {
680 var BSSGP_ConnHdlr vc_conn;
681 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200682 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100683 vc_conn.done;
684}
685
Harald Welte5b7c8122018-02-16 21:48:17 +0100686/* HLR never responds to UL REQ, expect ATTACH REJECT */
687private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100688 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100689 var RoutingAreaIdentificationV old_ra := f_random_RAI();
690
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200691 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 +0100692 f_gmm_auth();
693 /* Expect MSC to perform LU with HLR */
694 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
695 /* Never follow-up with ISD_REQ or UL_RES */
696 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200697 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100698 setverdict(pass);
699 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200700 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100701 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100702 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200703 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100704 }
705 }
706}
707testcase TC_attach_gsup_lu_timeout() runs on test_CT {
708 var BSSGP_ConnHdlr vc_conn;
709 f_init();
710 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200711 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100712 vc_conn.done;
713}
714
Harald Welteb7c14e92018-02-17 09:29:16 +0100715/* HLR rejects UL REQ, expect ATTACH REJECT */
716private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
717 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100718 var RoutingAreaIdentificationV old_ra := f_random_RAI();
719
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200720 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 +0100721 f_gmm_auth();
722 /* Expect MSC to perform LU with HLR */
723 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
724 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
725 }
726 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200727 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100728 setverdict(pass);
729 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200730 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100731 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
732 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200733 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100734 }
735 }
736}
737testcase TC_attach_gsup_lu_reject() runs on test_CT {
738 var BSSGP_ConnHdlr vc_conn;
739 f_init();
740 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200741 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100742 vc_conn.done;
743}
744
745
Harald Welte3823e2e2018-02-16 21:53:48 +0100746/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
747private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100748 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100749 var RoutingAreaIdentificationV old_ra := f_random_RAI();
750
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200751 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 +0100752 f_gmm_auth();
753 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100754 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100755
Alexander Couzens0e510e62018-07-28 23:06:00 +0200756 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100757 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
758 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200759 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100760 setverdict(pass);
761}
Harald Welte3823e2e2018-02-16 21:53:48 +0100762testcase TC_attach_combined() 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_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100767 vc_conn.done;
768}
769
Harald Welte76dee092018-02-16 22:12:59 +0100770/* Attempt of GPRS ATTACH in 'accept all' mode */
771private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100772 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100773 var RoutingAreaIdentificationV old_ra := f_random_RAI();
774
775 g_pars.net.expect_auth := false;
776
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200777 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 +0100778 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200779 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100780 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
781 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200782 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100783 setverdict(pass);
784}
785testcase TC_attach_accept_all() runs on test_CT {
786 var BSSGP_ConnHdlr vc_conn;
787 f_init();
788 f_sleep(1.0);
789 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200790 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100791 vc_conn.done;
792}
Harald Welte5b7c8122018-02-16 21:48:17 +0100793
Harald Welteb2124b22018-02-16 22:26:56 +0100794/* Attempt of GPRS ATTACH in 'accept all' mode */
795private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100796 var RoutingAreaIdentificationV old_ra := f_random_RAI();
797
798 /* Simulate a foreign IMSI */
799 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200800 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100801
802 g_pars.net.expect_auth := false;
803
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200804 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 +0100805 alt {
806 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200807 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100808 setverdict(pass);
809 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200810 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100811 setverdict(pass);
812 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200813 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200814 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200815 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200816 }
Harald Welteb2124b22018-02-16 22:26:56 +0100817 }
818}
819testcase TC_attach_closed() runs on test_CT {
820 var BSSGP_ConnHdlr vc_conn;
821 f_init();
822 f_sleep(1.0);
823 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
824 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200825 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100826 vc_conn.done;
827 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200828 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100829 vc_conn.done;
830}
831
Harald Welte04683d02018-02-16 22:43:45 +0100832/* Routing Area Update from Unknown TLLI -> REJECT */
833private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100834 var RoutingAreaIdentificationV old_ra := f_random_RAI();
835
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200836 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 +0100837 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200838 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100839 setverdict(pass);
840 }
841 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200842 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100843 }
844}
845testcase TC_rau_unknown() runs on test_CT {
846 var BSSGP_ConnHdlr vc_conn;
847 f_init();
848 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200849 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100850 vc_conn.done;
851}
852
Harald Welte91636de2018-02-17 10:16:14 +0100853private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
854 var BssgpDecoded bd;
855
856 /* first perform regular attach */
857 f_TC_attach(id);
858
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200859 f_routing_area_update(g_pars.ra);
860
Harald Welte91636de2018-02-17 10:16:14 +0100861}
862testcase TC_attach_rau() runs on test_CT {
863 var BSSGP_ConnHdlr vc_conn;
864 f_init();
865 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200866 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100867 vc_conn.done;
868}
Harald Welte04683d02018-02-16 22:43:45 +0100869
Harald Welte6abb9fe2018-02-17 15:24:48 +0100870/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200871function 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 +0100872 var BssgpDecoded bd;
873 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200874 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100875 if (expect_purge) {
876 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
877 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
878 }
879 T.start;
880 alt {
881 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
882 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200883 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100884 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200885 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100886 g_pars.ra := omit;
887 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200888 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100889 /* TODO: check if any PDP contexts are deactivated on network side? */
890 }
891 [power_off] T.timeout {
892 setverdict(pass);
893 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200894 [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 +0100895 g_pars.ra := omit;
896 setverdict(pass);
897 /* TODO: check if any PDP contexts are deactivated on network side? */
898 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200899 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100900 }
901}
902
903/* IMSI DETACH (non-power-off) for unknown TLLI */
904private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
905 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
906}
907testcase TC_detach_unknown_nopoweroff() runs on test_CT {
908 var BSSGP_ConnHdlr vc_conn;
909 f_init();
910 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200911 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100912 vc_conn.done;
913}
914
915/* IMSI DETACH (power-off) for unknown TLLI */
916private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
917 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
918}
919testcase TC_detach_unknown_poweroff() runs on test_CT {
920 var BSSGP_ConnHdlr vc_conn;
921 f_init();
922 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200923 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100924 vc_conn.done;
925}
926
927/* IMSI DETACH (non-power-off) for known TLLI */
928private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
929 /* first perform regular attach */
930 f_TC_attach(id);
931
932 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
933}
934testcase TC_detach_nopoweroff() runs on test_CT {
935 var BSSGP_ConnHdlr vc_conn;
936 f_init();
937 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200938 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100939 vc_conn.done;
940}
941
942/* IMSI DETACH (power-off) for known TLLI */
943private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
944 /* first perform regular attach */
945 f_TC_attach(id);
946
947 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
948}
949testcase TC_detach_poweroff() runs on test_CT {
950 var BSSGP_ConnHdlr vc_conn;
951 f_init();
952 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200953 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100954 vc_conn.done;
955}
956
Harald Welteeded9ad2018-02-17 20:57:34 +0100957type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100958 BIT3 tid, /* L3 Transaction ID */
959 BIT4 nsapi, /* SNDCP NSAPI */
960 BIT4 sapi, /* LLC SAPI */
961 QoSV qos, /* QoS parameters */
962 PDPAddressV addr, /* IP address */
963 octetstring apn optional, /* APN name */
964 ProtocolConfigOptionsV pco optional, /* protoco config opts */
965 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100966 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100967 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100968
Harald Welte822f9102018-02-18 20:39:06 +0100969 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
970 OCT4 ggsn_tei_u, /* GGSN TEI User */
971 octetstring ggsn_ip_c, /* GGSN IP Control */
972 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200973 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100974
Harald Welte822f9102018-02-18 20:39:06 +0100975 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
976 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
977 octetstring sgsn_ip_c optional, /* SGSN IP Control */
978 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100979};
980
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100981
982private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
983 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
984 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
985 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
986 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
987 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
988 f_gtp_register_teid(apars.ggsn_tei_c);
989 f_gtp_register_teid(apars.ggsn_tei_u);
990}
991
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200992function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100993 var boolean exp_rej := ispresent(apars.exp_rej_cause);
994 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200995 var template Recovery_gtpc recovery := omit;
996
997 if (send_recovery) {
998 recovery := ts_Recovery(apars.ggsn_restart_ctr);
999 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001000
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001001 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welteeded9ad2018-02-17 20:57:34 +01001002 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001003 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1004 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1005 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1006 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1007 apars.sgsn_tei_c, apars.gtp_resp_cause,
1008 apars.ggsn_tei_c, apars.ggsn_tei_u,
1009 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001010 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1011 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001012 }
1013 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001014 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001015 setverdict(pass);
1016 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001017 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001018 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001019 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001020 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001021 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001022 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001023 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001024 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001025 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001026 setverdict(pass);
1027 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001028 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +01001029 }
1030}
1031
Harald Welte6f203162018-02-18 22:04:55 +01001032function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
1033 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1034 var Gtp1cUnitdata g_ud;
1035
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001036 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
Harald Welte6f203162018-02-18 22:04:55 +01001037 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1038 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001039 BSSGP[0].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001040 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1041 }
1042 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001043 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001044 setverdict(pass);
1045 }
1046 [] as_xid(apars);
1047 }
1048}
1049
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001050function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001051 var Gtp1cUnitdata g_ud;
1052 var integer seq_nr := 23;
1053 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1054
Alexander Couzens0e510e62018-07-28 23:06:00 +02001055 BSSGP[0].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001056 if (error_ind) {
1057 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1058 } else {
1059 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1060 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001061
1062 timer T := 5.0;
1063 T.start;
1064
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001065 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001066 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001067 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Harald Welte57b9b7f2018-02-18 22:28:13 +01001068 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001069 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1070 repeat;
1071 }
1072 [] T.timeout {
1073 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1074 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001075 }
1076}
1077
Harald Welte6f203162018-02-18 22:04:55 +01001078
Harald Welteeded9ad2018-02-17 20:57:34 +01001079/* Table 10.5.156/3GPP TS 24.008 */
1080template (value) QoSV t_QosDefault := {
1081 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1082 delayClass := '100'B, /* best effort */
1083 spare1 := '00'B,
1084 precedenceClass := '010'B, /* normal */
1085 spare2 := '0'B,
1086 peakThroughput := '0000'B, /* subscribed */
1087 meanThroughput := '00000'B, /* subscribed */
1088 spare3 := '000'B,
1089 deliverErroneusSDU := omit,
1090 deliveryOrder := omit,
1091 trafficClass := omit,
1092 maxSDUSize := omit,
1093 maxBitrateUplink := omit,
1094 maxBitrateDownlink := omit,
1095 sduErrorRatio := omit,
1096 residualBER := omit,
1097 trafficHandlingPriority := omit,
1098 transferDelay := omit,
1099 guaranteedBitRateUplink := omit,
1100 guaranteedBitRateDownlink := omit,
1101 sourceStatisticsDescriptor := omit,
1102 signallingIndication := omit,
1103 spare4 := omit,
1104 maxBitrateDownlinkExt := omit,
1105 guaranteedBitRateDownlinkExt := omit,
1106 maxBitrateUplinkExt := omit,
1107 guaranteedBitRateUplinkExt := omit,
1108 maxBitrateDownlinkExt2 := omit,
1109 guaranteedBitRateDownlinkExt2 := omit,
1110 maxBitrateUplinkExt2 := omit,
1111 guaranteedBitRateUplinkExt2 := omit
1112}
1113
1114/* 10.5.6.4 / 3GPP TS 24.008 */
1115template (value) PDPAddressV t_AddrIPv4dyn := {
1116 pdpTypeOrg := '0001'B, /* IETF */
1117 spare := '0000'B,
1118 pdpTypeNum := '21'O, /* IPv4 */
1119 addressInfo := omit
1120}
1121template (value) PDPAddressV t_AddrIPv6dyn := {
1122 pdpTypeOrg := '0001'B, /* IETF */
1123 spare := '0000'B,
1124 pdpTypeNum := '53'O, /* IPv6 */
1125 addressInfo := omit
1126}
1127
Harald Welte37692d82018-02-18 15:21:34 +01001128template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001129 tid := '000'B,
1130 nsapi := '0101'B, /* < 5 are reserved */
1131 sapi := '0011'B, /* 3/5/9/11 */
1132 qos := t_QosDefault,
1133 addr := t_AddrIPv4dyn,
1134 apn := omit,
1135 pco := omit,
1136 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001137 gtp_resp_cause := int2oct(128, 1),
1138 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001139
1140 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001141 ggsn_tei_c := f_rnd_octstring(4),
1142 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001143 ggsn_ip_c := f_inet_addr(ggsn_ip),
1144 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001145 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001146
Harald Welteeded9ad2018-02-17 20:57:34 +01001147 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001148 sgsn_tei_u := omit,
1149 sgsn_ip_c := omit,
1150 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001151}
1152
Harald Welte37692d82018-02-18 15:21:34 +01001153template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1154 connId := 1,
1155 remName := f_inet_ntoa(ip),
1156 remPort := GTP1U_PORT
1157}
1158
1159template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1160 connId := 1,
1161 remName := f_inet_ntoa(ip),
1162 remPort := GTP1C_PORT
1163}
1164
1165private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1166 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1167 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1168}
1169
1170private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001171 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001172 repeat;
1173 }
1174}
1175
1176template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1177 pDU_SN_UNITDATA := {
1178 nsapi := nsapi,
1179 moreBit := ?,
1180 snPduType := '1'B,
1181 firstSegmentIndicator := ?,
1182 spareBit := ?,
1183 pcomp := ?,
1184 dcomp := ?,
1185 npduNumber := ?,
1186 segmentNumber := ?,
1187 npduNumberContinued := ?,
1188 dataSegmentSnUnitdataPdu := payload
1189 }
1190}
1191
1192/* simple case: single segment, no compression */
1193template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1194 pDU_SN_UNITDATA := {
1195 nsapi := nsapi,
1196 moreBit := '0'B,
1197 snPduType := '1'B,
1198 firstSegmentIndicator := '1'B,
1199 spareBit := '0'B,
1200 pcomp := '0000'B,
1201 dcomp := '0000'B,
1202 npduNumber := '0000'B,
1203 segmentNumber := '0000'B,
1204 npduNumberContinued := '00'O,
1205 dataSegmentSnUnitdataPdu := payload
1206 }
1207}
1208
1209/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1210private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1211 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1212 f_gtpu_send(apars, payload);
1213 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1214 alt {
1215 [] as_xid(apars);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001216 [] BSSGP[0].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001217 }
1218}
1219
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001220/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001221private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1222 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1223 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1224 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001225 BSSGP[0].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001226 /* Expect PDU via GTP from SGSN on simulated GGSN */
1227 alt {
1228 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1229 }
1230}
1231
Harald Welteeded9ad2018-02-17 20:57:34 +01001232private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001233 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001234
1235 /* first perform regular attach */
1236 f_TC_attach(id);
1237
1238 f_pdp_ctx_act(apars);
1239}
1240testcase TC_attach_pdp_act() runs on test_CT {
1241 var BSSGP_ConnHdlr vc_conn;
1242 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001243 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001244 vc_conn.done;
1245}
Harald Welteb2124b22018-02-16 22:26:56 +01001246
Harald Welte835b15f2018-02-18 14:39:11 +01001247/* PDP Context activation for not-attached subscriber; expect fail */
1248private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001249 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001250 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 +01001251 apars.apn, apars.pco));
1252 alt {
1253 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001254 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001255 setverdict(pass);
1256 }
1257 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1258 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001259 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001260 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001261 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001262 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001263 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001264 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001265 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001266 }
1267}
1268testcase TC_pdp_act_unattached() runs on test_CT {
1269 var BSSGP_ConnHdlr vc_conn;
1270 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001271 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001272 vc_conn.done;
1273}
1274
Harald Welte37692d82018-02-18 15:21:34 +01001275/* ATTACH + PDP CTX ACT + user plane traffic */
1276private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1277 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1278
1279 /* first perform regular attach */
1280 f_TC_attach(id);
1281 /* then activate PDP context */
1282 f_pdp_ctx_act(apars);
1283 /* then transceive a downlink PDU */
1284 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1285 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1286}
1287testcase TC_attach_pdp_act_user() runs on test_CT {
1288 var BSSGP_ConnHdlr vc_conn;
1289 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001290 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001291 vc_conn.done;
1292}
1293
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001294/* ATTACH + PDP CTX ACT; reject from GGSN */
1295private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1296 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1297
1298 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1299 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1300
1301 /* first perform regular attach */
1302 f_TC_attach(id);
1303 /* then activate PDP context */
1304 f_pdp_ctx_act(apars);
1305}
1306testcase TC_attach_pdp_act_ggsn_reject() 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_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001310 vc_conn.done;
1311}
Harald Welte835b15f2018-02-18 14:39:11 +01001312
Harald Welte6f203162018-02-18 22:04:55 +01001313/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1314private function f_TC_attach_pdp_act_user_deact_mo(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
1325 f_pdp_ctx_deact_mo(apars, '00'O);
1326}
1327testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1328 var BSSGP_ConnHdlr vc_conn;
1329 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001330 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 +01001331 vc_conn.done;
1332}
1333
Harald Welte57b9b7f2018-02-18 22:28:13 +01001334/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1335private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1336 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1337
1338 /* first perform regular attach */
1339 f_TC_attach(id);
1340 /* then activate PDP context */
1341 f_pdp_ctx_act(apars);
1342 /* then transceive a downlink PDU */
1343 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1344 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1345
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001346 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001347}
1348testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1349 var BSSGP_ConnHdlr vc_conn;
1350 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001351 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 +01001352 vc_conn.done;
1353}
1354
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001355/* ATTACH + ATTACH (2nd) */
1356private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1357 g_pars.t_guard := 5.0;
1358
1359 /* first perform regular attach */
1360 f_TC_attach(id);
1361
1362 /* second to perform regular attach */
1363 f_TC_attach(id);
1364}
1365
1366
1367testcase TC_attach_second_attempt() runs on test_CT {
1368 var BSSGP_ConnHdlr vc_conn;
1369 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001370 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001371 vc_conn.done;
1372}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001373
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001374private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001375 var Gtp1cUnitdata g_ud;
1376 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1377
1378 /* first perform regular attach */
1379 f_TC_attach(id);
1380 /* Activate a pdp context against the GGSN */
1381 f_pdp_ctx_act(apars);
1382 /* Wait to receive first echo request and send initial Restart counter */
1383 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1384 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1385 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1386 }
1387 /* Wait to receive second echo request and send incremented Restart
1388 counter. This will fake a restarted GGSN, and pdp ctx allocated
1389 should be released by SGSN */
1390 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1391 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1392 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1393 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1394 }
1395 var OCT1 cause_network_failure := int2oct(38, 1)
1396 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001397 [] 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 +02001398 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001399 setverdict(pass);
1400 }
1401 [] as_xid(apars);
1402 }
1403 setverdict(pass);
1404}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001405/* ATTACH + trigger Recovery procedure through EchoResp */
1406testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001407 var BSSGP_ConnHdlr vc_conn;
1408 g_use_echo := true
1409 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001410 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 +02001411 vc_conn.done;
1412 g_use_echo := false
1413}
1414
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001415private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1416 var Gtp1cUnitdata g_ud;
1417 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1418 var integer seq_nr := 23;
1419 var GtpPeer peer;
1420 /* first perform regular attach */
1421 f_TC_attach(id);
1422
1423 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1424 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1425 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1426 f_pdp_ctx_act(apars, true);
1427
1428 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1429/* received. */
1430 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1431
1432 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1433 would be great to have an active pdp context here before triggering
1434 Recovery, and making sure the the DEACT request is sent by the SGSN.
1435 */
1436
1437 /* Activate a pdp context against the GGSN, send incremented Recovery
1438 IE. This should trigger the recovery path, but still this specific
1439 CTX activation should work. */
1440 apars.exp_rej_cause := omit; /* default value for tests */
1441 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1442 f_pdp_ctx_act(apars, true);
1443
1444 setverdict(pass);
1445}
1446/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1447testcase TC_attach_restart_ctr_create() runs on test_CT {
1448 var BSSGP_ConnHdlr vc_conn;
1449 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001450 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 +02001451 vc_conn.done;
1452}
1453
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001454/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1455private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1456 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1457 var integer seq_nr := 23;
1458 var GtpPeer peer;
1459 var integer i;
1460
1461 /* first perform regular attach */
1462 f_TC_attach(id);
1463 /* then activate PDP context */
1464 f_pdp_ctx_act(apars);
1465
Alexander Couzens0e510e62018-07-28 23:06:00 +02001466 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001467 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1468 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1469
1470 for (i := 0; i < 5; i := i+1) {
1471 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001472 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001473 [] as_xid(apars);
1474 }
1475 }
1476
1477 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1478
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001479 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001480 setverdict(pass);
1481}
1482testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1483 var BSSGP_ConnHdlr vc_conn;
1484 f_init();
1485 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001486 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 +02001487 vc_conn.done;
1488}
1489
Alexander Couzens5e307b42018-05-22 18:12:20 +02001490private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1491 /* MS: perform regular attach */
1492 f_TC_attach(id);
1493
1494 /* HLR: cancel the location request */
1495 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1496 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001497
1498 /* ensure no Detach Request got received */
1499 timer T := 5.0;
1500 T.start;
1501 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001502 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001503 T.stop;
1504 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001505 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001506 }
1507 [] T.timeout {
1508 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001509 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001510 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001511 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001512 repeat;
1513 }
1514 }
1515}
1516
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001517/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1518private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1519 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1520
1521 /* first perform regular attach */
1522 f_TC_attach(id);
1523 /* then activate PDP context */
1524 f_pdp_ctx_act(apars);
1525 /* then transceive a downlink PDU */
1526 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1527
1528 /* Send Error indication as response from upload PDU and expect deact towards MS */
1529 f_pdp_ctx_deact_mt(apars, true);
1530}
1531testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1532 var BSSGP_ConnHdlr vc_conn;
1533 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001534 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 +02001535 vc_conn.done;
1536}
1537
Alexander Couzens5e307b42018-05-22 18:12:20 +02001538testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1539 /* MS <-> SGSN: GMM Attach
1540 * HLR -> SGSN: Cancel Location Request
1541 * HLR <- SGSN: Cancel Location Ack
1542 */
1543 var BSSGP_ConnHdlr vc_conn;
1544 f_init();
1545 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001546 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001547 vc_conn.done;
1548}
1549
1550
Alexander Couzensc87967a2018-05-22 16:09:54 +02001551private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1552 /* MS: perform regular attach */
1553 f_TC_attach(id);
1554
1555 /* HLR: cancel the location request */
1556 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1557 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1558 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1559
1560 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001561 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 +02001562 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001563
1564 setverdict(pass);
1565}
1566
1567testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1568 /* MS <-> SGSN: GMM Attach
1569 * HLR -> SGSN: Cancel Location Request
1570 * HLR <- SGSN: Cancel Location Ack
1571 * MS <- SGSN: Detach Request
1572 * SGSN-> MS: Detach Complete
1573 */
1574 var BSSGP_ConnHdlr vc_conn;
1575 f_init();
1576 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001577 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001578 vc_conn.done;
1579}
1580
1581
Alexander Couzens6c47f292018-05-22 17:09:49 +02001582private function f_hlr_location_cancel_request_unknown_subscriber(
1583 charstring id,
1584 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1585
1586 /* HLR: cancel the location request */
1587 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1588
1589 /* cause 2 = IMSI_UNKNOWN */
1590 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1591
1592 setverdict(pass);
1593}
1594
1595private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001596 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001597}
1598
1599testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1600 /* HLR -> SGSN: Cancel Location Request
1601 * HLR <- SGSN: Cancel Location Error
1602 */
1603
1604 var BSSGP_ConnHdlr vc_conn;
1605 f_init();
1606 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001607 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 +02001608 vc_conn.done;
1609}
1610
1611private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001612 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001613}
1614
1615testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1616 /* HLR -> SGSN: Cancel Location Request
1617 * HLR <- SGSN: Cancel Location Error
1618 */
1619
1620 var BSSGP_ConnHdlr vc_conn;
1621 f_init();
1622 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001623 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 +02001624 vc_conn.done;
1625}
1626
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001627private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1628 f_TC_attach(id);
1629 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1630}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001631
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001632testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1633 /* MS <-> SGSN: Attach
1634 * MS -> SGSN: Detach Req (Power off)
1635 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1636 */
1637 var BSSGP_ConnHdlr vc_conn;
1638 var integer id := 33;
1639 var charstring imsi := hex2str(f_gen_imsi(id));
1640
1641 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001642 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001643 vc_conn.done;
1644
1645 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1646}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001647
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001648/* Attempt an attach, but loose the Identification Request (IMEI) */
1649private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1650 var integer count_req := 0;
1651 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1652
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001653 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 +02001654
1655 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001656 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001657 /* break */
1658 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001659 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001660 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001661 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001662 repeat;
1663 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001664 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001665 /* ignore ID REQ IMEI */
1666 count_req := count_req + 1;
1667 repeat;
1668 }
1669 }
1670 if (count_req != 5) {
1671 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001672 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001673 }
1674 setverdict(pass);
1675}
1676
1677testcase TC_attach_no_imei_response() runs on test_CT {
1678 /* MS -> SGSN: Attach Request IMSI
1679 * MS <- SGSN: Identity Request IMSI (optional)
1680 * MS -> SGSN: Identity Response IMSI (optional)
1681 * MS <- SGSN: Identity Request IMEI
1682 * MS -x SGSN: no response
1683 * MS <- SGSN: re-send: Identity Request IMEI 4x
1684 * MS <- SGSN: Attach Reject
1685 */
1686 var BSSGP_ConnHdlr vc_conn;
1687 f_init();
1688 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001689 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 +02001690 vc_conn.done;
1691}
1692
Alexander Couzens53f20562018-06-12 16:24:12 +02001693/* Attempt an attach, but loose the Identification Request (IMSI) */
1694private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1695 var integer count_req := 0;
1696 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1697
1698 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1699 g_pars.p_tmsi := 'c0000035'O;
1700
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001701 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 +02001702
1703 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001704 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001705 /* break */
1706 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001707 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001708 /* ignore ID REQ IMSI */
1709 count_req := count_req + 1;
1710 repeat;
1711 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001712 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001713 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001714 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001715 repeat;
1716 }
1717 }
1718 if (count_req != 5) {
1719 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001720 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001721 }
1722 setverdict(pass);
1723}
1724
1725testcase TC_attach_no_imsi_response() runs on test_CT {
1726 /* MS -> SGSN: Attach Request TMSI (unknown)
1727 * MS <- SGSN: Identity Request IMEI (optional)
1728 * MS -> SGSN: Identity Response IMEI (optional)
1729 * MS <- SGSN: Identity Request IMSI
1730 * MS -x SGSN: no response
1731 * MS <- SGSN: re-send: Identity Request IMSI 4x
1732 * MS <- SGSN: Attach Reject
1733 */
1734 var BSSGP_ConnHdlr vc_conn;
1735 f_init();
1736 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001737 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 +02001738 vc_conn.done;
1739}
1740
Alexander Couzenscf818962018-06-05 18:00:00 +02001741private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1742 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1743}
1744
1745testcase TC_attach_check_subscriber_list() runs on test_CT {
1746 /* MS <-> SGSN: Attach
1747 * VTY -> SGSN: Check if MS is in subscriber cache
1748 */
1749 var BSSGP_ConnHdlr vc_conn;
1750 var integer id := 34;
1751 var charstring imsi := hex2str(f_gen_imsi(id));
1752
1753 f_init();
1754 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001755 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001756 vc_conn.done;
1757
1758 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1759 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1760}
1761
Alexander Couzensf9858652018-06-07 16:14:53 +02001762private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1763 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1764 var BssgpDecoded bd;
1765
1766 /* unregister the old IMSI */
1767 f_bssgp_client_unregister(g_pars.imsi);
1768 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001769 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001770 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001771
1772 /* there is no auth */
1773 g_pars.net.expect_auth := false;
1774
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001775 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 +02001776 f_gmm_auth();
1777 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001778 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001779 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001780 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001781 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001782 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001783 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001784 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001785 setverdict(pass);
1786 }
1787 }
1788}
Alexander Couzens03d12242018-08-07 16:13:52 +02001789
1790private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1791
1792 f_TC_attach_closed_foreign(id);
1793 f_TC_attach_closed_imsi_added(id);
1794
1795}
1796
1797
Alexander Couzensf9858652018-06-07 16:14:53 +02001798testcase TC_attach_closed_add_vty() runs on test_CT {
1799 /* VTY-> SGSN: policy close
1800 * MS -> SGSN: Attach Request
1801 * MS <- SGSN: Identity Request IMSI
1802 * MS -> SGSN: Identity Response IMSI
1803 * MS <- SGSN: Attach Reject
1804 * VTY-> SGSN: policy imsi-acl add IMSI
1805 * MS -> SGSN: Attach Request
1806 * MS <- SGSN: Identity Request IMSI
1807 * MS -> SGSN: Identity Response IMSI
1808 * MS <- SGSN: Identity Request IMEI
1809 * MS -> SGSN: Identity Response IMEI
1810 * MS <- SGSN: Attach Accept
1811 */
1812 var BSSGP_ConnHdlr vc_conn;
1813 f_init();
1814 f_sleep(1.0);
1815 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1816 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001817 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1818 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001819 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001820 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001821 vc_conn.done;
1822}
1823
Alexander Couzens0085bd72018-06-12 19:08:44 +02001824/* Attempt an attach, but never answer a Attach Complete */
1825private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1826 var integer count_req := 0;
1827
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001828 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 +02001829 f_gmm_auth();
1830
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001831 timer T := 10.0;
1832 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001833 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001834 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001835 /* break */
1836 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001837 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001838 /* ignore */
1839 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001840 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001841 repeat;
1842 }
1843 }
1844 if (count_req != 5) {
1845 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001846 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001847 }
1848 setverdict(pass);
1849}
1850
1851testcase TC_attach_check_complete_resend() runs on test_CT {
1852 /* MS -> SGSN: Attach Request IMSI
1853 * MS <- SGSN: Identity Request *
1854 * MS -> SGSN: Identity Response *
1855 * MS <- SGSN: Attach Complete 5x
1856 */
1857 var BSSGP_ConnHdlr vc_conn;
1858 f_init();
1859 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001860 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 +02001861 vc_conn.done;
1862}
1863
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001864private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
1865 var BssgpDecoded bd;
1866
1867 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001868 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 +02001869 alt {
1870 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001871 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001872 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001873 setverdict(pass);
1874 }
1875 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
1876 setverdict(fail, "Unexpected RAU Reject");
1877 mtc.stop;
1878 }
1879 [] BSSGP[bssgp].receive { repeat; }
1880 }
1881}
1882
Alexander Couzensbfda9212018-07-31 03:17:33 +02001883private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
1884 var BssgpDecoded bd;
1885
1886 /* first perform regular attach */
1887 f_TC_attach(id);
1888
1889 /* then send RAU */
1890 f_routing_area_update(g_pars.ra);
1891
1892 /* do another RAU */
1893 f_routing_area_update(g_pars.ra);
1894
1895 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1896}
1897
1898testcase TC_attach_rau_a_a() runs on test_CT {
1899 /* MS <-> SGSN: Successful Attach
1900 * MS -> SGSN: Routing Area Update Request
1901 * MS <- SGSN: Routing Area Update Accept
1902 * MS -> SGSN: Routing Area Update Request
1903 * MS <- SGSN: Routing Area Update Accept
1904 * MS -> SGSN: Detach (PowerOff)
1905 */
1906 var BSSGP_ConnHdlr vc_conn;
1907 f_init();
1908 f_sleep(1.0);
1909 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
1910 vc_conn.done;
1911}
1912
Alexander Couzensbe837bd2018-07-31 04:20:11 +02001913private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
1914 var BssgpDecoded bd;
1915
1916 f_TC_attach(id);
1917
1918 log("attach complete sending rau");
1919 f_routing_area_update(g_pars.ra, 0);
1920
1921 log("rau complete unregistering");
1922 f_bssgp_client_unregister(g_pars.imsi);
1923 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
1924
1925 log("sending second RAU via different RA");
1926 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
1927
1928 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
1929}
1930
1931testcase TC_attach_rau_a_b() runs on test_CT {
1932 /* MS <-> SGSN: Successful Attach
1933 * MS -> SGSN: Routing Area _a_ Update Request
1934 * MS <- SGSN: Routing Area _a_ Update Accept
1935 * MS -> SGSN: Routing Area _b_ Update Request
1936 * MS <- SGSN: Routing Area _b_ Update Accept
1937 * MS -> SGSN: Detach (PowerOff)
1938 */
1939 var BSSGP_ConnHdlr vc_conn;
1940 f_init();
1941 f_sleep(1.0);
1942 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
1943 vc_conn.done;
1944}
1945
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02001946private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
1947 var integer count_req := 0;
1948 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1949 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
1950 var BssgpDecoded bd;
1951
1952 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1953
1954 alt {
1955 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1956 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1957 mtc.stop;
1958 }
1959 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1960 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1961 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1962 repeat;
1963 }
1964 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1965 /* send out a second GMM_Attach Request.
1966 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
1967 * of the same content */
1968 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1969 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1970 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1971 }
1972 }
1973 f_sleep(1.0);
1974
1975 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
1976 alt {
1977 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1978 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1979 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1980 repeat;
1981 }
1982 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1983 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
1984 mtc.stop;
1985 }
1986 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1987 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1988 mtc.stop;
1989 }
1990 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
1991 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1992 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
1993 setverdict(pass);
1994 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
1995 }
1996 }
1997}
1998
1999testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2000 /* Testing if the SGSN ignore Attach Request with the exact same content */
2001 /* MS -> SGSN: Attach Request IMSI
2002 * MS <- SGSN: Identity Request IMSI (optional)
2003 * MS -> SGSN: Identity Response IMSI (optional)
2004 * MS <- SGSN: Identity Request IMEI
2005 * MS -> SGSN: Attach Request (2nd)
2006 * MS <- SGSN: Identity Response IMEI
2007 * MS <- SGSN: Attach Accept
2008 * MS -> SGSN: Attach Complete
2009 */
2010 var BSSGP_ConnHdlr vc_conn;
2011 f_init();
2012 f_sleep(1.0);
2013 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2014 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2015 vc_conn.done;
2016}
2017
Harald Welte5ac31492018-02-15 20:39:13 +01002018control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002019 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002020 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002021 execute( TC_attach_umts_aka_umts_res() );
2022 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002023 execute( TC_attach_auth_id_timeout() );
2024 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002025 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002026 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002027 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002028 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002029 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002030 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002031 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002032 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002033 execute( TC_attach_closed_add_vty(), 20.0 );
2034 execute( TC_attach_check_subscriber_list(), 20.0 );
2035 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002036 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002037 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2038 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2039 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2040 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002041 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002042 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002043 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002044 execute( TC_attach_rau_a_b() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002045 execute( TC_detach_unknown_nopoweroff() );
2046 execute( TC_detach_unknown_poweroff() );
2047 execute( TC_detach_nopoweroff() );
2048 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002049 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002050 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002051 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002052 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002053 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002054 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002055 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002056 execute( TC_attach_restart_ctr_echo() );
2057 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002058 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002059 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002060 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Welte5ac31492018-02-15 20:39:13 +01002061}
Harald Welte96a33b02018-02-04 10:36:22 +01002062
2063
2064
2065}