blob: 6bf2d605d32074d50bf2b59ad77625110e53d082 [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
47 NSConfiguration mp_nsconfig := {
48 local_udp_port := 23000,
49 local_ip := "127.0.0.1",
50 remote_udp_port := 21000,
51 remote_ip := "127.0.0.1",
52 nsvci := 0,
53 nsei := 2342
54 };
Harald Welte5ac31492018-02-15 20:39:13 +010055};
56
57type record GbInstance {
58 NS_CT vc_NS,
59 BSSGP_CT vc_BSSGP,
60 BssgpConfig cfg
61};
Harald Welte96a33b02018-02-04 10:36:22 +010062
63type component test_CT {
Harald Welte5ac31492018-02-15 20:39:13 +010064 var GbInstance g_gb[3];
Harald Welte96a33b02018-02-04 10:36:22 +010065
Harald Welte5ac31492018-02-15 20:39:13 +010066 var GSUP_Emulation_CT vc_GSUP;
67 var IPA_Emulation_CT vc_GSUP_IPA;
68 /* only to get events from IPA underneath GSUP */
69 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010070
Harald Welteeded9ad2018-02-17 20:57:34 +010071 var GTP_Emulation_CT vc_GTP;
72
Harald Weltebd194722018-02-16 22:11:08 +010073 port TELNETasp_PT SGSNVTY;
74
Harald Welte96a33b02018-02-04 10:36:22 +010075 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +020076 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +010077};
78
Harald Welteeded9ad2018-02-17 20:57:34 +010079type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +010080 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +010081 timer g_Tguard;
Harald Welte5ac31492018-02-15 20:39:13 +010082}
83
84type record SGSN_ConnHdlrNetworkPars {
85 boolean expect_ptmsi,
86 boolean expect_auth,
87 boolean expect_ciph
88};
89
90type record BSSGP_ConnHdlrPars {
91 /* IMEI of the simulated ME */
92 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +020093 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +010094 hexstring imsi,
95 /* MSISDN of the simulated MS (probably unused) */
96 hexstring msisdn,
97 /* P-TMSI allocated to the simulated MS */
98 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +010099 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100100 /* TLLI of the simulated MS */
101 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100102 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100103 RoutingAreaIdentificationV ra optional,
104 BssgpCellId bssgp_cell_id,
105 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100106 SGSN_ConnHdlrNetworkPars net,
107 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100108};
109
Harald Welte3fdbe822018-02-18 19:10:18 +0100110private function f_init_gb(inout GbInstance gb, charstring id) runs on test_CT {
111 gb.vc_NS := NS_CT.create(id & "-NS");
112 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP");
Harald Welte5ac31492018-02-15 20:39:13 +0100113 /* connect lower end of BSSGP emulation with NS upper port */
114 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
115 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
116 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
117
Alexander Couzens2c12b242018-07-31 00:30:11 +0200118 gb.vc_NS.start(NSStart(mp_nsconfig));
Harald Welte5ac31492018-02-15 20:39:13 +0100119 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
120}
121
122private function f_init_gsup(charstring id) runs on test_CT {
123 id := id & "-GSUP";
124 var GsupOps ops := {
125 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
126 };
127
128 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
129 vc_GSUP := GSUP_Emulation_CT.create(id);
130
131 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
132 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
133 /* we use this hack to get events like ASP_IPA_EVENT_UP */
134 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
135
136 vc_GSUP.start(GSUP_Emulation.main(ops, id));
137 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
138
139 /* wait for incoming connection to GSUP port before proceeding */
140 timer T := 10.0;
141 T.start;
142 alt {
143 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
144 [] T.timeout {
145 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200146 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100147 }
148 }
149}
150
Harald Welteeded9ad2018-02-17 20:57:34 +0100151private function f_init_gtp(charstring id) runs on test_CT {
152 id := id & "-GTP";
153
154 var GtpEmulationCfg gtp_cfg := {
155 gtpc_bind_ip := mp_ggsn_ip,
156 gtpc_bind_port := GTP1C_PORT,
157 gtpu_bind_ip := mp_ggsn_ip,
158 gtpu_bind_port := GTP1U_PORT,
159 sgsn_role := false
160 };
161
162 vc_GTP := GTP_Emulation_CT.create(id);
163 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
164}
165
Harald Weltebd194722018-02-16 22:11:08 +0100166private function f_init_vty() runs on test_CT {
167 map(self:SGSNVTY, system:SGSNVTY);
168 f_vty_set_prompts(SGSNVTY);
169 f_vty_transceive(SGSNVTY, "enable");
170 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
171}
172
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200173private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
174 if (enable) {
175 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
176 } else {
177 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
178 }
179}
180
Harald Weltebd194722018-02-16 22:11:08 +0100181
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100182function f_init(BcdMccMnc mcc_mnc := '26242F'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100183 if (g_initialized == true) {
184 return;
185 }
186 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100187 g_gb[0].cfg := {
188 nsei := 96,
189 bvci := 196,
190 cell_id := {
191 ra_id := {
192 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100193 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100194 rac := 0
195 },
196 cell_id := 20960
197 },
198 sgsn_role := false
199 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200200 g_gb[1].cfg := {
201 nsei := 97,
202 bvci := 210,
203 cell_id := {
204 ra_id := {
205 lai := {
206 mcc_mnc := mcc_mnc, lac := 13200},
207 rac := 0
208 },
209 cell_id := 20961
210 },
211 sgsn_role := false
212 };
213 g_gb[2].cfg := {
214 nsei := 98,
215 bvci := 220,
216 cell_id := {
217 ra_id := {
218 lai := {
219 mcc_mnc := mcc_mnc, lac := 13300},
220 rac := 0
221 },
222 cell_id := 20962
223 },
224 sgsn_role := false
225 };
Harald Welte96a33b02018-02-04 10:36:22 +0100226
Harald Welte3fdbe822018-02-18 19:10:18 +0100227 f_init_gb(g_gb[0], "SGSN_Test-Gb0");
Harald Welte5ac31492018-02-15 20:39:13 +0100228 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100229 f_init_gtp("SGSN_Test");
Harald Weltebd194722018-02-16 22:11:08 +0100230 f_init_vty();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200231 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100232}
Harald Welte96a33b02018-02-04 10:36:22 +0100233
Harald Welte5ac31492018-02-15 20:39:13 +0100234type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
235
236/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte62e29582018-02-16 21:17:11 +0100237function f_start_handler(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix,
238 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100239runs on test_CT return BSSGP_ConnHdlr {
240 var BSSGP_ConnHdlr vc_conn;
241 var SGSN_ConnHdlrNetworkPars net_pars := {
242 expect_ptmsi := true,
243 expect_auth := true,
244 expect_ciph := false
245 };
246 var BSSGP_ConnHdlrPars pars := {
247 imei := f_gen_imei(imsi_suffix),
248 imsi := f_gen_imsi(imsi_suffix),
249 msisdn := f_gen_msisdn(imsi_suffix),
250 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100251 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100252 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100253 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100254 ra := omit,
255 bssgp_cell_id := gb.cfg.cell_id,
256 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100257 net := net_pars,
258 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100259 };
260
261 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens0e510e62018-07-28 23:06:00 +0200262 connect(vc_conn:BSSGP[0], gb.vc_BSSGP:BSSGP_SP);
263 connect(vc_conn:BSSGP_PROC[0], gb.vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100264
265 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
266 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
267
Harald Welteeded9ad2018-02-17 20:57:34 +0100268 connect(vc_conn:GTP, vc_GTP:CLIENT);
269 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
270
Harald Welte5ac31492018-02-15 20:39:13 +0100271 vc_conn.start(f_handler_init(fn, id, pars));
272 return vc_conn;
273}
274
Harald Welte62e29582018-02-16 21:17:11 +0100275private altstep as_Tguard() runs on BSSGP_ConnHdlr {
276 [] g_Tguard.timeout {
277 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200278 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100279 }
280}
281
Harald Welte5ac31492018-02-15 20:39:13 +0100282/* first function called in every ConnHdlr */
283private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
284runs on BSSGP_ConnHdlr {
285 /* do some common stuff like setting up g_pars */
286 g_pars := pars;
287
288 /* register with BSSGP core */
289 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
290 /* tell GSUP dispatcher to send this IMSI to us */
291 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100292 /* tell GTP dispatcher to send this IMSI to us */
293 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100294
Harald Welte62e29582018-02-16 21:17:11 +0100295 g_Tguard.start(pars.t_guard);
296 activate(as_Tguard());
297
Harald Welte5ac31492018-02-15 20:39:13 +0100298 /* call the user-supplied test case function */
299 fn.apply(id);
300 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100301}
302
303/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100304 * Detach without Attach
305 * SM procedures without attach / RAU
306 * ATTACH / RAU
307 ** with / without authentication
308 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100309 * re-transmissions of LLC frames
310 * PDP Context activation
311 ** with different GGSN config in SGSN VTY
312 ** with different PDP context type (v4/v6/v46)
313 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100314 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100315 */
316
317testcase TC_wait_ns_up() runs on test_CT {
318 f_init();
319 f_sleep(20.0);
320}
321
Harald Welte5ac31492018-02-15 20:39:13 +0100322altstep as_mm_identity() runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100323 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200324 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100325 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens0e510e62018-07-28 23:06:00 +0200326 BSSGP[0].send(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100327 repeat;
328 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200329 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100330 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens0e510e62018-07-28 23:06:00 +0200331 BSSGP[0].send(ts_GMM_ID_RESP(mi));
Harald Welte5ac31492018-02-15 20:39:13 +0100332 repeat;
333 }
334}
Harald Welte96a33b02018-02-04 10:36:22 +0100335
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200336/* perform GMM authentication (if expected).
337 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
338 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
339function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100340 var BssgpDecoded bd;
341 var PDU_L3_MS_SGSN l3_mo;
342 var PDU_L3_SGSN_MS l3_mt;
343 var default di := activate(as_mm_identity());
344 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200345 var GSUP_IE auth_tuple;
346 var template AuthenticationParameterAUTNTLV autn;
347
348 if (umts_aka_challenge) {
349 g_pars.vec := f_gen_auth_vec_3g();
350 autn := {
351 elementIdentifier := '28'O,
352 lengthIndicator := lengthof(g_pars.vec.autn),
353 autnValue := g_pars.vec.autn
354 };
355
356 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
357 g_pars.vec.sres,
358 g_pars.vec.kc,
359 g_pars.vec.ik,
360 g_pars.vec.ck,
361 g_pars.vec.autn,
362 g_pars.vec.res));
363 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
364 } else {
365 g_pars.vec := f_gen_auth_vec_2g();
366 autn := omit;
367 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
368 g_pars.vec.sres,
369 g_pars.vec.kc));
370 log("GSUP sends only 2G auth tuple", auth_tuple);
371 }
Harald Welte5ac31492018-02-15 20:39:13 +0100372 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
373 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200374
375 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
376 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200377 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
Harald Welte5ac31492018-02-15 20:39:13 +0100378 l3_mt := bd.l3_mt;
379 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200380 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
381
382 if (umts_aka_challenge and not force_gsm_sres) {
383 /* set UMTS response instead */
384 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
385 valueField := substr(g_pars.vec.res, 0, 4)
386 };
387 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
388 elementIdentifier := '21'O,
389 lengthIndicator := lengthof(g_pars.vec.res) - 4,
390 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
391 };
392 }
393
394 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100395 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
396 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
397 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
398 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
399 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200400 BSSGP[0].send(l3_mo);
Harald Welte76dee092018-02-16 22:12:59 +0100401 } else {
402 /* wait for identity procedure */
403 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100404 }
Harald Welte76dee092018-02-16 22:12:59 +0100405
Harald Welte5ac31492018-02-15 20:39:13 +0100406 deactivate(di);
407}
408
Harald Weltef70997d2018-02-17 10:11:19 +0100409function f_upd_ptmsi_and_tlli(OCT4 p_tmsi) runs on BSSGP_ConnHdlr {
410 g_pars.p_tmsi := p_tmsi;
411 /* update TLLI */
412 g_pars.tlli_old := g_pars.tlli;
413 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
414 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli);
415}
416
Harald Welte04683d02018-02-16 22:43:45 +0100417function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
418 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100419 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
420 if (not (g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc == aa_plmn)) {
421 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
422 & "; expected " & hex2str(g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200423 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100424 }
Harald Welte04683d02018-02-16 22:43:45 +0100425 g_pars.ra := aa.routingAreaIdentification;
426 if (ispresent(aa.allocatedPTMSI)) {
427 if (not g_pars.net.expect_ptmsi) {
428 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200429 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100430 }
Harald Weltef70997d2018-02-17 10:11:19 +0100431 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100432 }
433 if (ispresent(aa.msIdentity)) {
434 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200435 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100436 }
437 /* P-TMSI.sig */
438 if (ispresent(aa.ptmsiSignature)) {
439 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
440 }
441 /* updateTimer */
442 // aa.readyTimer
443 /* T3302, T3319, T3323, T3312_ext, T3324 */
444}
445
Harald Welte91636de2018-02-17 10:16:14 +0100446function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra) runs on BSSGP_ConnHdlr {
447 /* mandatory IE */
448 g_pars.ra := ra.routingAreaId;
449 if (ispresent(ra.allocatedPTMSI)) {
450 if (not g_pars.net.expect_ptmsi) {
451 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200452 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100453 }
454 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
455 }
456 if (ispresent(ra.msIdentity)) {
457 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200458 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100459 }
460 /* P-TMSI.sig */
461 if (ispresent(ra.ptmsiSignature)) {
462 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
463 }
464 /* updateTimer */
465 // aa.readyTimer
466 /* T3302, T3319, T3323, T3312_ext, T3324 */
467}
468
469
Harald Welte5a4fa042018-02-16 20:59:21 +0100470function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
471 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
472}
473
Harald Welte23178c52018-02-17 09:36:33 +0100474/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100475private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100476 if (ispresent(g_pars.p_tmsi)) {
477 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
478 } else {
479 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
480 }
481}
482
Harald Welte311ec272018-02-17 09:40:03 +0100483private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100484 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100485 /* Expect MSC to perform LU with HLR */
486 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100487 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
488 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
489 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100490 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
491 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
492}
493
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200494private function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100495 var BssgpDecoded bd;
Harald Welte5a4fa042018-02-16 20:59:21 +0100496 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200497 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 +0100498
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200499 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
500 * 3G auth vectors */
501 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
502 /* The thing is, if the solSACapability is 'omit', then the
503 * revisionLevelIndicatior is at the wrong place! */
504 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
505
Alexander Couzens0e510e62018-07-28 23:06:00 +0200506 BSSGP[0].send(attach_req);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200507 f_gmm_auth(umts_aka_challenge, force_gsm_sres);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200508 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100509 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100510
Alexander Couzens0e510e62018-07-28 23:06:00 +0200511 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100512 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
513 }
514 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200515 BSSGP[0].send(ts_GMM_ATTACH_COMPL);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200516}
517
518private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
519 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100520 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100521}
522
523testcase TC_attach() runs on test_CT {
524 var BSSGP_ConnHdlr vc_conn;
525 f_init();
526 f_sleep(1.0);
527 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1);
528 vc_conn.done;
529}
530
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100531testcase TC_attach_mnc3() runs on test_CT {
532 var BSSGP_ConnHdlr vc_conn;
533 f_init('023042'H);
534 f_sleep(1.0);
535 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1001);
536 vc_conn.done;
537}
538
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200539private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
540 f_gmm_attach(true, false);
541 setverdict(pass);
542}
543testcase TC_attach_umts_aka_umts_res() runs on test_CT {
544 var BSSGP_ConnHdlr vc_conn;
545 f_init();
546 f_sleep(1.0);
547 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb[0], 1002);
548 vc_conn.done;
549}
550
551private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
552 f_gmm_attach(true, true);
553 setverdict(pass);
554}
555testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
556 var BSSGP_ConnHdlr vc_conn;
557 f_init();
558 f_sleep(1.0);
559 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb[0], 1003);
560 vc_conn.done;
561}
562
Harald Welte5b7c8122018-02-16 21:48:17 +0100563/* MS never responds to ID REQ, expect ATTACH REJECT */
564private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100565 var RoutingAreaIdentificationV old_ra := f_random_RAI();
566
Alexander Couzens0e510e62018-07-28 23:06:00 +0200567 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100568 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200569 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100570 /* don't send ID Response */
571 repeat;
572 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200573 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100574 setverdict(pass);
575 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200576 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100577 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200578 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100579 }
580 }
581}
582testcase TC_attach_auth_id_timeout() runs on test_CT {
583 var BSSGP_ConnHdlr vc_conn;
584 f_init();
585 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb[0], 2, 40.0);
586 vc_conn.done;
587}
588
589/* HLR never responds to SAI REQ, expect ATTACH REJECT */
590private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100591 var RoutingAreaIdentificationV old_ra := f_random_RAI();
592
Alexander Couzens0e510e62018-07-28 23:06:00 +0200593 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100594 alt {
595 [] as_mm_identity();
596 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
597 }
598 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200599 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100600 setverdict(pass);
601}
602testcase TC_attach_auth_sai_timeout() runs on test_CT {
603 var BSSGP_ConnHdlr vc_conn;
604 f_init();
605 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb[0], 3);
606 vc_conn.done;
607}
608
Harald Weltefe253882018-02-17 09:25:00 +0100609/* HLR rejects SAI, expect ATTACH REJECT */
610private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100611 var RoutingAreaIdentificationV old_ra := f_random_RAI();
612
Alexander Couzens0e510e62018-07-28 23:06:00 +0200613 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100614 alt {
615 [] as_mm_identity();
616 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
617 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
618 }
619 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200620 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100621 setverdict(pass);
622}
623testcase TC_attach_auth_sai_reject() runs on test_CT {
624 var BSSGP_ConnHdlr vc_conn;
625 f_init();
Harald Welteb7c14e92018-02-17 09:29:16 +0100626 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb[0], 4);
Harald Weltefe253882018-02-17 09:25:00 +0100627 vc_conn.done;
628}
629
Harald Welte5b7c8122018-02-16 21:48:17 +0100630/* HLR never responds to UL REQ, expect ATTACH REJECT */
631private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100632 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100633 var RoutingAreaIdentificationV old_ra := f_random_RAI();
634
Alexander Couzens0e510e62018-07-28 23:06:00 +0200635 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100636 f_gmm_auth();
637 /* Expect MSC to perform LU with HLR */
638 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
639 /* Never follow-up with ISD_REQ or UL_RES */
640 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200641 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100642 setverdict(pass);
643 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200644 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100645 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100646 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200647 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100648 }
649 }
650}
651testcase TC_attach_gsup_lu_timeout() runs on test_CT {
652 var BSSGP_ConnHdlr vc_conn;
653 f_init();
654 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100655 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb[0], 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100656 vc_conn.done;
657}
658
Harald Welteb7c14e92018-02-17 09:29:16 +0100659/* HLR rejects UL REQ, expect ATTACH REJECT */
660private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
661 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100662 var RoutingAreaIdentificationV old_ra := f_random_RAI();
663
Alexander Couzens0e510e62018-07-28 23:06:00 +0200664 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100665 f_gmm_auth();
666 /* Expect MSC to perform LU with HLR */
667 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
668 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
669 }
670 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200671 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100672 setverdict(pass);
673 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200674 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100675 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
676 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200677 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100678 }
679 }
680}
681testcase TC_attach_gsup_lu_reject() runs on test_CT {
682 var BSSGP_ConnHdlr vc_conn;
683 f_init();
684 f_sleep(1.0);
685 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb[0], 6);
686 vc_conn.done;
687}
688
689
Harald Welte3823e2e2018-02-16 21:53:48 +0100690/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
691private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100692 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100693 var RoutingAreaIdentificationV old_ra := f_random_RAI();
694
Alexander Couzens0e510e62018-07-28 23:06:00 +0200695 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100696 f_gmm_auth();
697 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100698 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100699
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);
702 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200703 BSSGP[0].send(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100704 setverdict(pass);
705}
Harald Welte3823e2e2018-02-16 21:53:48 +0100706testcase TC_attach_combined() runs on test_CT {
707 var BSSGP_ConnHdlr vc_conn;
708 f_init();
709 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100710 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb[0], 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100711 vc_conn.done;
712}
713
Harald Welte76dee092018-02-16 22:12:59 +0100714/* Attempt of GPRS ATTACH in 'accept all' mode */
715private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100716 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100717 var RoutingAreaIdentificationV old_ra := f_random_RAI();
718
719 g_pars.net.expect_auth := false;
720
Alexander Couzens0e510e62018-07-28 23:06:00 +0200721 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100722 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200723 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100724 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
725 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200726 BSSGP[0].send(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100727 setverdict(pass);
728}
729testcase TC_attach_accept_all() runs on test_CT {
730 var BSSGP_ConnHdlr vc_conn;
731 f_init();
732 f_sleep(1.0);
733 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Harald Welteb7c14e92018-02-17 09:29:16 +0100734 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 8);
Harald Welte76dee092018-02-16 22:12:59 +0100735 vc_conn.done;
736}
Harald Welte5b7c8122018-02-16 21:48:17 +0100737
Harald Welteb2124b22018-02-16 22:26:56 +0100738/* Attempt of GPRS ATTACH in 'accept all' mode */
739private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100740 var RoutingAreaIdentificationV old_ra := f_random_RAI();
741
742 /* Simulate a foreign IMSI */
743 g_pars.imsi := '001010123456789'H;
744 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
745
746 g_pars.net.expect_auth := false;
747
Alexander Couzens0e510e62018-07-28 23:06:00 +0200748 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100749 alt {
750 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200751 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100752 setverdict(pass);
753 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200754 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100755 setverdict(pass);
756 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200757 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200758 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200759 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200760 }
Harald Welteb2124b22018-02-16 22:26:56 +0100761 }
762}
763testcase TC_attach_closed() runs on test_CT {
764 var BSSGP_ConnHdlr vc_conn;
765 f_init();
766 f_sleep(1.0);
767 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
768 /* test with foreign IMSI: Must Reject */
Harald Welteb7c14e92018-02-17 09:29:16 +0100769 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100770 vc_conn.done;
771 /* test with home IMSI: Must Accept */
Harald Welteb7c14e92018-02-17 09:29:16 +0100772 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100773 vc_conn.done;
774}
775
Harald Welte04683d02018-02-16 22:43:45 +0100776/* Routing Area Update from Unknown TLLI -> REJECT */
777private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100778 var RoutingAreaIdentificationV old_ra := f_random_RAI();
779
Alexander Couzens0e510e62018-07-28 23:06:00 +0200780 BSSGP[0].send(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +0100781 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200782 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100783 setverdict(pass);
784 }
785 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200786 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100787 }
788}
789testcase TC_rau_unknown() runs on test_CT {
790 var BSSGP_ConnHdlr vc_conn;
791 f_init();
792 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100793 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb[0], 11);
Harald Welte04683d02018-02-16 22:43:45 +0100794 vc_conn.done;
795}
796
Harald Welte91636de2018-02-17 10:16:14 +0100797private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
798 var BssgpDecoded bd;
799
800 /* first perform regular attach */
801 f_TC_attach(id);
802
803 /* then send RAU */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200804 BSSGP[0].send(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit));
Harald Welte91636de2018-02-17 10:16:14 +0100805 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200806 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Harald Welte91636de2018-02-17 10:16:14 +0100807 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept);
Alexander Couzens0e510e62018-07-28 23:06:00 +0200808 BSSGP[0].send(ts_GMM_RAU_COMPL);
Harald Welte91636de2018-02-17 10:16:14 +0100809 setverdict(pass);
810 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200811 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
Harald Welte91636de2018-02-17 10:16:14 +0100812 setverdict(fail, "Unexpected RAU Reject");
Daniel Willmannafce8662018-07-06 23:11:32 +0200813 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100814 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200815 [] BSSGP[0].receive { repeat; }
Harald Welte91636de2018-02-17 10:16:14 +0100816 }
817}
818testcase TC_attach_rau() runs on test_CT {
819 var BSSGP_ConnHdlr vc_conn;
820 f_init();
821 f_sleep(1.0);
822 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb[0], 12);
823 vc_conn.done;
824}
Harald Welte04683d02018-02-16 22:43:45 +0100825
Harald Welte6abb9fe2018-02-17 15:24:48 +0100826/* general GPRS DETACH helper */
827function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge) runs on BSSGP_ConnHdlr {
828 var BssgpDecoded bd;
829 timer T := 5.0;
Alexander Couzens0e510e62018-07-28 23:06:00 +0200830 BSSGP[0].send(ts_GMM_DET_REQ_MO(detach_type, power_off));
Harald Welte6abb9fe2018-02-17 15:24:48 +0100831 if (expect_purge) {
832 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
833 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
834 }
835 T.start;
836 alt {
837 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
838 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200839 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100840 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200841 [power_off] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100842 g_pars.ra := omit;
843 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200844 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100845 /* TODO: check if any PDP contexts are deactivated on network side? */
846 }
847 [power_off] T.timeout {
848 setverdict(pass);
849 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200850 [not power_off] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100851 g_pars.ra := omit;
852 setverdict(pass);
853 /* TODO: check if any PDP contexts are deactivated on network side? */
854 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200855 [] BSSGP[0].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100856 }
857}
858
859/* IMSI DETACH (non-power-off) for unknown TLLI */
860private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
861 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
862}
863testcase TC_detach_unknown_nopoweroff() runs on test_CT {
864 var BSSGP_ConnHdlr vc_conn;
865 f_init();
866 f_sleep(1.0);
867 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb[0], 13);
868 vc_conn.done;
869}
870
871/* IMSI DETACH (power-off) for unknown TLLI */
872private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
873 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
874}
875testcase TC_detach_unknown_poweroff() runs on test_CT {
876 var BSSGP_ConnHdlr vc_conn;
877 f_init();
878 f_sleep(1.0);
879 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb[0], 14);
880 vc_conn.done;
881}
882
883/* IMSI DETACH (non-power-off) for known TLLI */
884private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
885 /* first perform regular attach */
886 f_TC_attach(id);
887
888 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
889}
890testcase TC_detach_nopoweroff() runs on test_CT {
891 var BSSGP_ConnHdlr vc_conn;
892 f_init();
893 f_sleep(1.0);
894 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb[0], 15);
895 vc_conn.done;
896}
897
898/* IMSI DETACH (power-off) for known TLLI */
899private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
900 /* first perform regular attach */
901 f_TC_attach(id);
902
903 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
904}
905testcase TC_detach_poweroff() runs on test_CT {
906 var BSSGP_ConnHdlr vc_conn;
907 f_init();
908 f_sleep(1.0);
909 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb[0], 16);
910 vc_conn.done;
911}
912
Harald Welteeded9ad2018-02-17 20:57:34 +0100913type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100914 BIT3 tid, /* L3 Transaction ID */
915 BIT4 nsapi, /* SNDCP NSAPI */
916 BIT4 sapi, /* LLC SAPI */
917 QoSV qos, /* QoS parameters */
918 PDPAddressV addr, /* IP address */
919 octetstring apn optional, /* APN name */
920 ProtocolConfigOptionsV pco optional, /* protoco config opts */
921 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100922 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100923 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100924
Harald Welte822f9102018-02-18 20:39:06 +0100925 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
926 OCT4 ggsn_tei_u, /* GGSN TEI User */
927 octetstring ggsn_ip_c, /* GGSN IP Control */
928 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200929 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100930
Harald Welte822f9102018-02-18 20:39:06 +0100931 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
932 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
933 octetstring sgsn_ip_c optional, /* SGSN IP Control */
934 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100935};
936
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100937
938private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
939 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
940 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
941 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
942 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
943 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
944 f_gtp_register_teid(apars.ggsn_tei_c);
945 f_gtp_register_teid(apars.ggsn_tei_u);
946}
947
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200948function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100949 var boolean exp_rej := ispresent(apars.exp_rej_cause);
950 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200951 var template Recovery_gtpc recovery := omit;
952
953 if (send_recovery) {
954 recovery := ts_Recovery(apars.ggsn_restart_ctr);
955 }
Harald Welteeded9ad2018-02-17 20:57:34 +0100956
Alexander Couzens0e510e62018-07-28 23:06:00 +0200957 BSSGP[0].send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welteeded9ad2018-02-17 20:57:34 +0100958 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100959 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
960 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
961 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
962 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
963 apars.sgsn_tei_c, apars.gtp_resp_cause,
964 apars.ggsn_tei_c, apars.ggsn_tei_u,
965 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200966 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
967 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +0100968 }
969 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200970 [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 +0100971 setverdict(pass);
972 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200973 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100974 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +0200975 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +0100976 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200977 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100978 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +0200979 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +0100980 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200981 [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 +0100982 setverdict(pass);
983 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100984 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +0100985 }
986}
987
Harald Welte6f203162018-02-18 22:04:55 +0100988function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
989 var boolean exp_rej := ispresent(apars.exp_rej_cause);
990 var Gtp1cUnitdata g_ud;
991
Alexander Couzens0e510e62018-07-28 23:06:00 +0200992 BSSGP[0].send(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
Harald Welte6f203162018-02-18 22:04:55 +0100993 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
994 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzens0e510e62018-07-28 23:06:00 +0200995 BSSGP[0].clear;
Harald Welte6f203162018-02-18 22:04:55 +0100996 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
997 }
998 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200999 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001000 setverdict(pass);
1001 }
1002 [] as_xid(apars);
1003 }
1004}
1005
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001006function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001007 var Gtp1cUnitdata g_ud;
1008 var integer seq_nr := 23;
1009 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1010
Alexander Couzens0e510e62018-07-28 23:06:00 +02001011 BSSGP[0].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001012 if (error_ind) {
1013 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1014 } else {
1015 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1016 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001017
1018 timer T := 5.0;
1019 T.start;
1020
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001021 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001022 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
1023 BSSGP[0].send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Harald Welte57b9b7f2018-02-18 22:28:13 +01001024 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001025 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1026 repeat;
1027 }
1028 [] T.timeout {
1029 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1030 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001031 }
1032}
1033
Harald Welte6f203162018-02-18 22:04:55 +01001034
Harald Welteeded9ad2018-02-17 20:57:34 +01001035/* Table 10.5.156/3GPP TS 24.008 */
1036template (value) QoSV t_QosDefault := {
1037 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1038 delayClass := '100'B, /* best effort */
1039 spare1 := '00'B,
1040 precedenceClass := '010'B, /* normal */
1041 spare2 := '0'B,
1042 peakThroughput := '0000'B, /* subscribed */
1043 meanThroughput := '00000'B, /* subscribed */
1044 spare3 := '000'B,
1045 deliverErroneusSDU := omit,
1046 deliveryOrder := omit,
1047 trafficClass := omit,
1048 maxSDUSize := omit,
1049 maxBitrateUplink := omit,
1050 maxBitrateDownlink := omit,
1051 sduErrorRatio := omit,
1052 residualBER := omit,
1053 trafficHandlingPriority := omit,
1054 transferDelay := omit,
1055 guaranteedBitRateUplink := omit,
1056 guaranteedBitRateDownlink := omit,
1057 sourceStatisticsDescriptor := omit,
1058 signallingIndication := omit,
1059 spare4 := omit,
1060 maxBitrateDownlinkExt := omit,
1061 guaranteedBitRateDownlinkExt := omit,
1062 maxBitrateUplinkExt := omit,
1063 guaranteedBitRateUplinkExt := omit,
1064 maxBitrateDownlinkExt2 := omit,
1065 guaranteedBitRateDownlinkExt2 := omit,
1066 maxBitrateUplinkExt2 := omit,
1067 guaranteedBitRateUplinkExt2 := omit
1068}
1069
1070/* 10.5.6.4 / 3GPP TS 24.008 */
1071template (value) PDPAddressV t_AddrIPv4dyn := {
1072 pdpTypeOrg := '0001'B, /* IETF */
1073 spare := '0000'B,
1074 pdpTypeNum := '21'O, /* IPv4 */
1075 addressInfo := omit
1076}
1077template (value) PDPAddressV t_AddrIPv6dyn := {
1078 pdpTypeOrg := '0001'B, /* IETF */
1079 spare := '0000'B,
1080 pdpTypeNum := '53'O, /* IPv6 */
1081 addressInfo := omit
1082}
1083
Harald Welte37692d82018-02-18 15:21:34 +01001084template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001085 tid := '000'B,
1086 nsapi := '0101'B, /* < 5 are reserved */
1087 sapi := '0011'B, /* 3/5/9/11 */
1088 qos := t_QosDefault,
1089 addr := t_AddrIPv4dyn,
1090 apn := omit,
1091 pco := omit,
1092 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001093 gtp_resp_cause := int2oct(128, 1),
1094 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001095
1096 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001097 ggsn_tei_c := f_rnd_octstring(4),
1098 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001099 ggsn_ip_c := f_inet_addr(ggsn_ip),
1100 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001101 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001102
Harald Welteeded9ad2018-02-17 20:57:34 +01001103 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001104 sgsn_tei_u := omit,
1105 sgsn_ip_c := omit,
1106 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001107}
1108
Harald Welte37692d82018-02-18 15:21:34 +01001109template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1110 connId := 1,
1111 remName := f_inet_ntoa(ip),
1112 remPort := GTP1U_PORT
1113}
1114
1115template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1116 connId := 1,
1117 remName := f_inet_ntoa(ip),
1118 remPort := GTP1C_PORT
1119}
1120
1121private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1122 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1123 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1124}
1125
1126private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001127 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001128 repeat;
1129 }
1130}
1131
1132template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1133 pDU_SN_UNITDATA := {
1134 nsapi := nsapi,
1135 moreBit := ?,
1136 snPduType := '1'B,
1137 firstSegmentIndicator := ?,
1138 spareBit := ?,
1139 pcomp := ?,
1140 dcomp := ?,
1141 npduNumber := ?,
1142 segmentNumber := ?,
1143 npduNumberContinued := ?,
1144 dataSegmentSnUnitdataPdu := payload
1145 }
1146}
1147
1148/* simple case: single segment, no compression */
1149template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1150 pDU_SN_UNITDATA := {
1151 nsapi := nsapi,
1152 moreBit := '0'B,
1153 snPduType := '1'B,
1154 firstSegmentIndicator := '1'B,
1155 spareBit := '0'B,
1156 pcomp := '0000'B,
1157 dcomp := '0000'B,
1158 npduNumber := '0000'B,
1159 segmentNumber := '0000'B,
1160 npduNumberContinued := '00'O,
1161 dataSegmentSnUnitdataPdu := payload
1162 }
1163}
1164
1165/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1166private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1167 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1168 f_gtpu_send(apars, payload);
1169 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1170 alt {
1171 [] as_xid(apars);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001172 [] BSSGP[0].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001173 }
1174}
1175
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001176/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001177private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1178 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1179 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1180 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001181 BSSGP[0].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001182 /* Expect PDU via GTP from SGSN on simulated GGSN */
1183 alt {
1184 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1185 }
1186}
1187
Harald Welteeded9ad2018-02-17 20:57:34 +01001188private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001189 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001190
1191 /* first perform regular attach */
1192 f_TC_attach(id);
1193
1194 f_pdp_ctx_act(apars);
1195}
1196testcase TC_attach_pdp_act() runs on test_CT {
1197 var BSSGP_ConnHdlr vc_conn;
1198 f_init();
1199 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1200 vc_conn.done;
1201}
Harald Welteb2124b22018-02-16 22:26:56 +01001202
Harald Welte835b15f2018-02-18 14:39:11 +01001203/* PDP Context activation for not-attached subscriber; expect fail */
1204private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001205 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001206 BSSGP[0].send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001207 apars.apn, apars.pco));
1208 alt {
1209 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001210 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001211 setverdict(pass);
1212 }
1213 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1214 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001215 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001216 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001217 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001218 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001219 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001220 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001221 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001222 }
1223}
1224testcase TC_pdp_act_unattached() runs on test_CT {
1225 var BSSGP_ConnHdlr vc_conn;
1226 f_init();
1227 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1228 vc_conn.done;
1229}
1230
Harald Welte37692d82018-02-18 15:21:34 +01001231/* ATTACH + PDP CTX ACT + user plane traffic */
1232private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1233 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1234
1235 /* first perform regular attach */
1236 f_TC_attach(id);
1237 /* then activate PDP context */
1238 f_pdp_ctx_act(apars);
1239 /* then transceive a downlink PDU */
1240 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1241 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1242}
1243testcase TC_attach_pdp_act_user() runs on test_CT {
1244 var BSSGP_ConnHdlr vc_conn;
1245 f_init();
1246 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1247 vc_conn.done;
1248}
1249
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001250/* ATTACH + PDP CTX ACT; reject from GGSN */
1251private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1252 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1253
1254 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1255 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1256
1257 /* first perform regular attach */
1258 f_TC_attach(id);
1259 /* then activate PDP context */
1260 f_pdp_ctx_act(apars);
1261}
1262testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1263 var BSSGP_ConnHdlr vc_conn;
1264 f_init();
1265 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1266 vc_conn.done;
1267}
Harald Welte835b15f2018-02-18 14:39:11 +01001268
Harald Welte6f203162018-02-18 22:04:55 +01001269/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1270private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1271 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1272
1273 /* first perform regular attach */
1274 f_TC_attach(id);
1275 /* then activate PDP context */
1276 f_pdp_ctx_act(apars);
1277 /* then transceive a downlink PDU */
1278 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1279 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1280
1281 f_pdp_ctx_deact_mo(apars, '00'O);
1282}
1283testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1284 var BSSGP_ConnHdlr vc_conn;
1285 f_init();
1286 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1287 vc_conn.done;
1288}
1289
Harald Welte57b9b7f2018-02-18 22:28:13 +01001290/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1291private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1292 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1293
1294 /* first perform regular attach */
1295 f_TC_attach(id);
1296 /* then activate PDP context */
1297 f_pdp_ctx_act(apars);
1298 /* then transceive a downlink PDU */
1299 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1300 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1301
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001302 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001303}
1304testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1305 var BSSGP_ConnHdlr vc_conn;
1306 f_init();
1307 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1308 vc_conn.done;
1309}
1310
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001311/* ATTACH + ATTACH (2nd) */
1312private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1313 g_pars.t_guard := 5.0;
1314
1315 /* first perform regular attach */
1316 f_TC_attach(id);
1317
1318 /* second to perform regular attach */
1319 f_TC_attach(id);
1320}
1321
1322
1323testcase TC_attach_second_attempt() runs on test_CT {
1324 var BSSGP_ConnHdlr vc_conn;
1325 f_init();
1326 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1327 vc_conn.done;
1328}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001329
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001330private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001331 var Gtp1cUnitdata g_ud;
1332 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1333
1334 /* first perform regular attach */
1335 f_TC_attach(id);
1336 /* Activate a pdp context against the GGSN */
1337 f_pdp_ctx_act(apars);
1338 /* Wait to receive first echo request and send initial Restart counter */
1339 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1340 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1341 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1342 }
1343 /* Wait to receive second echo request and send incremented Restart
1344 counter. This will fake a restarted GGSN, and pdp ctx allocated
1345 should be released by SGSN */
1346 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1347 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1348 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1349 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1350 }
1351 var OCT1 cause_network_failure := int2oct(38, 1)
1352 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001353 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
1354 BSSGP[0].send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001355 setverdict(pass);
1356 }
1357 [] as_xid(apars);
1358 }
1359 setverdict(pass);
1360}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001361/* ATTACH + trigger Recovery procedure through EchoResp */
1362testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001363 var BSSGP_ConnHdlr vc_conn;
1364 g_use_echo := true
1365 f_init();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001366 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_echo), testcasename(), g_gb[0], 23, 30.0);
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001367 vc_conn.done;
1368 g_use_echo := false
1369}
1370
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001371private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1372 var Gtp1cUnitdata g_ud;
1373 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1374 var integer seq_nr := 23;
1375 var GtpPeer peer;
1376 /* first perform regular attach */
1377 f_TC_attach(id);
1378
1379 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1380 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1381 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1382 f_pdp_ctx_act(apars, true);
1383
1384 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1385/* received. */
1386 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1387
1388 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1389 would be great to have an active pdp context here before triggering
1390 Recovery, and making sure the the DEACT request is sent by the SGSN.
1391 */
1392
1393 /* Activate a pdp context against the GGSN, send incremented Recovery
1394 IE. This should trigger the recovery path, but still this specific
1395 CTX activation should work. */
1396 apars.exp_rej_cause := omit; /* default value for tests */
1397 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1398 f_pdp_ctx_act(apars, true);
1399
1400 setverdict(pass);
1401}
1402/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1403testcase TC_attach_restart_ctr_create() runs on test_CT {
1404 var BSSGP_ConnHdlr vc_conn;
1405 f_init();
1406 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb[0], 24, 30.0);
1407 vc_conn.done;
1408}
1409
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001410/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1411private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1412 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1413 var integer seq_nr := 23;
1414 var GtpPeer peer;
1415 var integer i;
1416
1417 /* first perform regular attach */
1418 f_TC_attach(id);
1419 /* then activate PDP context */
1420 f_pdp_ctx_act(apars);
1421
Alexander Couzens0e510e62018-07-28 23:06:00 +02001422 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001423 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1424 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1425
1426 for (i := 0; i < 5; i := i+1) {
1427 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001428 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001429 [] as_xid(apars);
1430 }
1431 }
1432
1433 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1434
Alexander Couzens0e510e62018-07-28 23:06:00 +02001435 BSSGP[0].send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001436 setverdict(pass);
1437}
1438testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1439 var BSSGP_ConnHdlr vc_conn;
1440 f_init();
1441 f_sleep(1.0);
1442 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb[0], 25, 60.0);
1443 vc_conn.done;
1444}
1445
Alexander Couzens5e307b42018-05-22 18:12:20 +02001446private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1447 /* MS: perform regular attach */
1448 f_TC_attach(id);
1449
1450 /* HLR: cancel the location request */
1451 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1452 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001453
1454 /* ensure no Detach Request got received */
1455 timer T := 5.0;
1456 T.start;
1457 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001458 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001459 T.stop;
1460 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001461 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001462 }
1463 [] T.timeout {
1464 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001465 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001466 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001467 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001468 repeat;
1469 }
1470 }
1471}
1472
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001473/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1474private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1475 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1476
1477 /* first perform regular attach */
1478 f_TC_attach(id);
1479 /* then activate PDP context */
1480 f_pdp_ctx_act(apars);
1481 /* then transceive a downlink PDU */
1482 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1483
1484 /* Send Error indication as response from upload PDU and expect deact towards MS */
1485 f_pdp_ctx_deact_mt(apars, true);
1486}
1487testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1488 var BSSGP_ConnHdlr vc_conn;
1489 f_init();
1490 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb[0], 26);
1491 vc_conn.done;
1492}
1493
Alexander Couzens5e307b42018-05-22 18:12:20 +02001494testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1495 /* MS <-> SGSN: GMM Attach
1496 * HLR -> SGSN: Cancel Location Request
1497 * HLR <- SGSN: Cancel Location Ack
1498 */
1499 var BSSGP_ConnHdlr vc_conn;
1500 f_init();
1501 f_sleep(1.0);
1502 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1503 vc_conn.done;
1504}
1505
1506
Alexander Couzensc87967a2018-05-22 16:09:54 +02001507private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1508 /* MS: perform regular attach */
1509 f_TC_attach(id);
1510
1511 /* HLR: cancel the location request */
1512 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1513 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1514 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1515
1516 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001517 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1518 BSSGP[0].send(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001519
1520 setverdict(pass);
1521}
1522
1523testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1524 /* MS <-> SGSN: GMM Attach
1525 * HLR -> SGSN: Cancel Location Request
1526 * HLR <- SGSN: Cancel Location Ack
1527 * MS <- SGSN: Detach Request
1528 * SGSN-> MS: Detach Complete
1529 */
1530 var BSSGP_ConnHdlr vc_conn;
1531 f_init();
1532 f_sleep(1.0);
1533 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1534 vc_conn.done;
1535}
1536
1537
Alexander Couzens6c47f292018-05-22 17:09:49 +02001538private function f_hlr_location_cancel_request_unknown_subscriber(
1539 charstring id,
1540 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1541
1542 /* HLR: cancel the location request */
1543 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1544
1545 /* cause 2 = IMSI_UNKNOWN */
1546 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1547
1548 setverdict(pass);
1549}
1550
1551private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001552 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001553}
1554
1555testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1556 /* HLR -> SGSN: Cancel Location Request
1557 * HLR <- SGSN: Cancel Location Error
1558 */
1559
1560 var BSSGP_ConnHdlr vc_conn;
1561 f_init();
1562 f_sleep(1.0);
1563 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1564 vc_conn.done;
1565}
1566
1567private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001568 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001569}
1570
1571testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1572 /* HLR -> SGSN: Cancel Location Request
1573 * HLR <- SGSN: Cancel Location Error
1574 */
1575
1576 var BSSGP_ConnHdlr vc_conn;
1577 f_init();
1578 f_sleep(1.0);
1579 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1580 vc_conn.done;
1581}
1582
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001583private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1584 f_TC_attach(id);
1585 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1586}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001587
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001588testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1589 /* MS <-> SGSN: Attach
1590 * MS -> SGSN: Detach Req (Power off)
1591 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1592 */
1593 var BSSGP_ConnHdlr vc_conn;
1594 var integer id := 33;
1595 var charstring imsi := hex2str(f_gen_imsi(id));
1596
1597 f_init();
1598 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb[0], id);
1599 vc_conn.done;
1600
1601 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1602}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001603
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001604/* Attempt an attach, but loose the Identification Request (IMEI) */
1605private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1606 var integer count_req := 0;
1607 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1608
Alexander Couzens0e510e62018-07-28 23:06:00 +02001609 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001610
1611 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001612 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001613 /* break */
1614 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001615 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001616 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001617 BSSGP[0].send(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001618 repeat;
1619 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001620 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001621 /* ignore ID REQ IMEI */
1622 count_req := count_req + 1;
1623 repeat;
1624 }
1625 }
1626 if (count_req != 5) {
1627 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001628 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001629 }
1630 setverdict(pass);
1631}
1632
1633testcase TC_attach_no_imei_response() runs on test_CT {
1634 /* MS -> SGSN: Attach Request IMSI
1635 * MS <- SGSN: Identity Request IMSI (optional)
1636 * MS -> SGSN: Identity Response IMSI (optional)
1637 * MS <- SGSN: Identity Request IMEI
1638 * MS -x SGSN: no response
1639 * MS <- SGSN: re-send: Identity Request IMEI 4x
1640 * MS <- SGSN: Attach Reject
1641 */
1642 var BSSGP_ConnHdlr vc_conn;
1643 f_init();
1644 f_sleep(1.0);
1645 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1646 vc_conn.done;
1647}
1648
Alexander Couzens53f20562018-06-12 16:24:12 +02001649/* Attempt an attach, but loose the Identification Request (IMSI) */
1650private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1651 var integer count_req := 0;
1652 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1653
1654 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1655 g_pars.p_tmsi := 'c0000035'O;
1656
Alexander Couzens0e510e62018-07-28 23:06:00 +02001657 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02001658
1659 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001660 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001661 /* break */
1662 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001663 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001664 /* ignore ID REQ IMSI */
1665 count_req := count_req + 1;
1666 repeat;
1667 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001668 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001669 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001670 BSSGP[0].send(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001671 repeat;
1672 }
1673 }
1674 if (count_req != 5) {
1675 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001676 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001677 }
1678 setverdict(pass);
1679}
1680
1681testcase TC_attach_no_imsi_response() runs on test_CT {
1682 /* MS -> SGSN: Attach Request TMSI (unknown)
1683 * MS <- SGSN: Identity Request IMEI (optional)
1684 * MS -> SGSN: Identity Response IMEI (optional)
1685 * MS <- SGSN: Identity Request IMSI
1686 * MS -x SGSN: no response
1687 * MS <- SGSN: re-send: Identity Request IMSI 4x
1688 * MS <- SGSN: Attach Reject
1689 */
1690 var BSSGP_ConnHdlr vc_conn;
1691 f_init();
1692 f_sleep(1.0);
1693 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1694 vc_conn.done;
1695}
1696
Alexander Couzenscf818962018-06-05 18:00:00 +02001697private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1698 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1699}
1700
1701testcase TC_attach_check_subscriber_list() runs on test_CT {
1702 /* MS <-> SGSN: Attach
1703 * VTY -> SGSN: Check if MS is in subscriber cache
1704 */
1705 var BSSGP_ConnHdlr vc_conn;
1706 var integer id := 34;
1707 var charstring imsi := hex2str(f_gen_imsi(id));
1708
1709 f_init();
1710 f_sleep(1.0);
1711 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], id);
1712 vc_conn.done;
1713
1714 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1715 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1716}
1717
Alexander Couzensf9858652018-06-07 16:14:53 +02001718private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1719 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1720 var BssgpDecoded bd;
1721
1722 /* unregister the old IMSI */
1723 f_bssgp_client_unregister(g_pars.imsi);
1724 /* Simulate a foreign IMSI */
1725 g_pars.imsi := '001010123456789'H;
1726 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
1727
1728 /* there is no auth */
1729 g_pars.net.expect_auth := false;
1730
Alexander Couzens0e510e62018-07-28 23:06:00 +02001731 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02001732 f_gmm_auth();
1733 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001734 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001735 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001736 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001737 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001738 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001739 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001740 BSSGP[0].send(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001741 setverdict(pass);
1742 }
1743 }
1744}
1745testcase TC_attach_closed_add_vty() runs on test_CT {
1746 /* VTY-> SGSN: policy close
1747 * MS -> SGSN: Attach Request
1748 * MS <- SGSN: Identity Request IMSI
1749 * MS -> SGSN: Identity Response IMSI
1750 * MS <- SGSN: Attach Reject
1751 * VTY-> SGSN: policy imsi-acl add IMSI
1752 * MS -> SGSN: Attach Request
1753 * MS <- SGSN: Identity Request IMSI
1754 * MS -> SGSN: Identity Response IMSI
1755 * MS <- SGSN: Identity Request IMEI
1756 * MS -> SGSN: Identity Response IMEI
1757 * MS <- SGSN: Attach Accept
1758 */
1759 var BSSGP_ConnHdlr vc_conn;
1760 f_init();
1761 f_sleep(1.0);
1762 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1763 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
1764 /* test with foreign IMSI: Must Reject */
1765 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
1766 vc_conn.done;
1767 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456789");
1768 /* test with same IMSI: Must Accept */
1769 vc_conn := f_start_handler(refers(f_TC_attach_closed_imsi_added), testcasename(), g_gb[0], 10);
1770 vc_conn.done;
1771}
1772
Alexander Couzens0085bd72018-06-12 19:08:44 +02001773/* Attempt an attach, but never answer a Attach Complete */
1774private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1775 var integer count_req := 0;
1776
Alexander Couzens0e510e62018-07-28 23:06:00 +02001777 BSSGP[0].send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02001778 f_gmm_auth();
1779
1780 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001781 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001782 /* break */
1783 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001784 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001785 /* ignore */
1786 count_req := count_req + 1;
1787 repeat;
1788 }
1789 }
1790 if (count_req != 5) {
1791 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001792 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001793 }
1794 setverdict(pass);
1795}
1796
1797testcase TC_attach_check_complete_resend() runs on test_CT {
1798 /* MS -> SGSN: Attach Request IMSI
1799 * MS <- SGSN: Identity Request *
1800 * MS -> SGSN: Identity Response *
1801 * MS <- SGSN: Attach Complete 5x
1802 */
1803 var BSSGP_ConnHdlr vc_conn;
1804 f_init();
1805 f_sleep(1.0);
1806 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb[0], 36, 60.0);
1807 vc_conn.done;
1808}
1809
Harald Welte5ac31492018-02-15 20:39:13 +01001810control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001811 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001812 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001813 execute( TC_attach_umts_aka_umts_res() );
1814 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001815 execute( TC_attach_auth_id_timeout() );
1816 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001817 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001818 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001819 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001820 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001821 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001822 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001823 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001824 execute( TC_attach_no_imsi_response() );
Alexander Couzensf9858652018-06-07 16:14:53 +02001825 execute( TC_attach_closed_add_vty(), 10.0 );
Alexander Couzenscf818962018-06-05 18:00:00 +02001826 execute( TC_attach_check_subscriber_list(), 10.0 );
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001827 execute( TC_attach_detach_check_subscriber_list(), 10.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02001828 execute( TC_attach_check_complete_resend() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001829 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001830 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1831 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1832 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001833 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001834 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001835 execute( TC_detach_unknown_nopoweroff() );
1836 execute( TC_detach_unknown_poweroff() );
1837 execute( TC_detach_nopoweroff() );
1838 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001839 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001840 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001841 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001842 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001843 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001844 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001845 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001846 execute( TC_attach_restart_ctr_echo() );
1847 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001848 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001849 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Harald Welte5ac31492018-02-15 20:39:13 +01001850}
Harald Welte96a33b02018-02-04 10:36:22 +01001851
1852
1853
1854}