blob: 6c94d147a3ac22f6fbcd67c34208fd24dbb2e3ab [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";
Harald Welte5ac31492018-02-15 20:39:13 +010046};
47
48type record GbInstance {
49 NS_CT vc_NS,
50 BSSGP_CT vc_BSSGP,
51 BssgpConfig cfg
52};
Harald Welte96a33b02018-02-04 10:36:22 +010053
54type component test_CT {
Harald Welte5ac31492018-02-15 20:39:13 +010055 var GbInstance g_gb[3];
Harald Welte96a33b02018-02-04 10:36:22 +010056
Harald Welte5ac31492018-02-15 20:39:13 +010057 var GSUP_Emulation_CT vc_GSUP;
58 var IPA_Emulation_CT vc_GSUP_IPA;
59 /* only to get events from IPA underneath GSUP */
60 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010061
Harald Welteeded9ad2018-02-17 20:57:34 +010062 var GTP_Emulation_CT vc_GTP;
63
Harald Weltebd194722018-02-16 22:11:08 +010064 port TELNETasp_PT SGSNVTY;
65
Harald Welte96a33b02018-02-04 10:36:22 +010066 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +020067 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +010068};
69
Harald Welteeded9ad2018-02-17 20:57:34 +010070type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +010071 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +010072 timer g_Tguard;
Harald Welte5ac31492018-02-15 20:39:13 +010073}
74
75type record SGSN_ConnHdlrNetworkPars {
76 boolean expect_ptmsi,
77 boolean expect_auth,
78 boolean expect_ciph
79};
80
81type record BSSGP_ConnHdlrPars {
82 /* IMEI of the simulated ME */
83 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +020084 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +010085 hexstring imsi,
86 /* MSISDN of the simulated MS (probably unused) */
87 hexstring msisdn,
88 /* P-TMSI allocated to the simulated MS */
89 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +010090 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +010091 /* TLLI of the simulated MS */
92 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +010093 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +010094 RoutingAreaIdentificationV ra optional,
95 BssgpCellId bssgp_cell_id,
96 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +010097 SGSN_ConnHdlrNetworkPars net,
98 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +010099};
100
Harald Welte3fdbe822018-02-18 19:10:18 +0100101private function f_init_gb(inout GbInstance gb, charstring id) runs on test_CT {
102 gb.vc_NS := NS_CT.create(id & "-NS");
103 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP");
Harald Welte5ac31492018-02-15 20:39:13 +0100104 /* connect lower end of BSSGP emulation with NS upper port */
105 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
106 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
107 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
108
109 gb.vc_NS.start(NSStart());
110 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
111}
112
113private function f_init_gsup(charstring id) runs on test_CT {
114 id := id & "-GSUP";
115 var GsupOps ops := {
116 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
117 };
118
119 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
120 vc_GSUP := GSUP_Emulation_CT.create(id);
121
122 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
123 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
124 /* we use this hack to get events like ASP_IPA_EVENT_UP */
125 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
126
127 vc_GSUP.start(GSUP_Emulation.main(ops, id));
128 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
129
130 /* wait for incoming connection to GSUP port before proceeding */
131 timer T := 10.0;
132 T.start;
133 alt {
134 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
135 [] T.timeout {
136 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200137 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100138 }
139 }
140}
141
Harald Welteeded9ad2018-02-17 20:57:34 +0100142private function f_init_gtp(charstring id) runs on test_CT {
143 id := id & "-GTP";
144
145 var GtpEmulationCfg gtp_cfg := {
146 gtpc_bind_ip := mp_ggsn_ip,
147 gtpc_bind_port := GTP1C_PORT,
148 gtpu_bind_ip := mp_ggsn_ip,
149 gtpu_bind_port := GTP1U_PORT,
150 sgsn_role := false
151 };
152
153 vc_GTP := GTP_Emulation_CT.create(id);
154 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
155}
156
Harald Weltebd194722018-02-16 22:11:08 +0100157private function f_init_vty() runs on test_CT {
158 map(self:SGSNVTY, system:SGSNVTY);
159 f_vty_set_prompts(SGSNVTY);
160 f_vty_transceive(SGSNVTY, "enable");
161 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
162}
163
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200164private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
165 if (enable) {
166 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
167 } else {
168 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
169 }
170}
171
Harald Weltebd194722018-02-16 22:11:08 +0100172
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100173function f_init(BcdMccMnc mcc_mnc := '26242F'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100174 if (g_initialized == true) {
175 return;
176 }
177 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100178 g_gb[0].cfg := {
179 nsei := 96,
180 bvci := 196,
181 cell_id := {
182 ra_id := {
183 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100184 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100185 rac := 0
186 },
187 cell_id := 20960
188 },
189 sgsn_role := false
190 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200191 g_gb[1].cfg := {
192 nsei := 97,
193 bvci := 210,
194 cell_id := {
195 ra_id := {
196 lai := {
197 mcc_mnc := mcc_mnc, lac := 13200},
198 rac := 0
199 },
200 cell_id := 20961
201 },
202 sgsn_role := false
203 };
204 g_gb[2].cfg := {
205 nsei := 98,
206 bvci := 220,
207 cell_id := {
208 ra_id := {
209 lai := {
210 mcc_mnc := mcc_mnc, lac := 13300},
211 rac := 0
212 },
213 cell_id := 20962
214 },
215 sgsn_role := false
216 };
Harald Welte96a33b02018-02-04 10:36:22 +0100217
Harald Welte3fdbe822018-02-18 19:10:18 +0100218 f_init_gb(g_gb[0], "SGSN_Test-Gb0");
Harald Welte5ac31492018-02-15 20:39:13 +0100219 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100220 f_init_gtp("SGSN_Test");
Harald Weltebd194722018-02-16 22:11:08 +0100221 f_init_vty();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200222 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100223}
Harald Welte96a33b02018-02-04 10:36:22 +0100224
Harald Welte5ac31492018-02-15 20:39:13 +0100225type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
226
227/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte62e29582018-02-16 21:17:11 +0100228function f_start_handler(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix,
229 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100230runs on test_CT return BSSGP_ConnHdlr {
231 var BSSGP_ConnHdlr vc_conn;
232 var SGSN_ConnHdlrNetworkPars net_pars := {
233 expect_ptmsi := true,
234 expect_auth := true,
235 expect_ciph := false
236 };
237 var BSSGP_ConnHdlrPars pars := {
238 imei := f_gen_imei(imsi_suffix),
239 imsi := f_gen_imsi(imsi_suffix),
240 msisdn := f_gen_msisdn(imsi_suffix),
241 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100242 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100243 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100244 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100245 ra := omit,
246 bssgp_cell_id := gb.cfg.cell_id,
247 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100248 net := net_pars,
249 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100250 };
251
252 vc_conn := BSSGP_ConnHdlr.create(id);
253 connect(vc_conn:BSSGP, gb.vc_BSSGP:BSSGP_SP);
254 connect(vc_conn:BSSGP_PROC, gb.vc_BSSGP:BSSGP_PROC);
255
256 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
257 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
258
Harald Welteeded9ad2018-02-17 20:57:34 +0100259 connect(vc_conn:GTP, vc_GTP:CLIENT);
260 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
261
Harald Welte5ac31492018-02-15 20:39:13 +0100262 vc_conn.start(f_handler_init(fn, id, pars));
263 return vc_conn;
264}
265
Harald Welte62e29582018-02-16 21:17:11 +0100266private altstep as_Tguard() runs on BSSGP_ConnHdlr {
267 [] g_Tguard.timeout {
268 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200269 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100270 }
271}
272
Harald Welte5ac31492018-02-15 20:39:13 +0100273/* first function called in every ConnHdlr */
274private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
275runs on BSSGP_ConnHdlr {
276 /* do some common stuff like setting up g_pars */
277 g_pars := pars;
278
279 /* register with BSSGP core */
280 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
281 /* tell GSUP dispatcher to send this IMSI to us */
282 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100283 /* tell GTP dispatcher to send this IMSI to us */
284 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100285
Harald Welte62e29582018-02-16 21:17:11 +0100286 g_Tguard.start(pars.t_guard);
287 activate(as_Tguard());
288
Harald Welte5ac31492018-02-15 20:39:13 +0100289 /* call the user-supplied test case function */
290 fn.apply(id);
291 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100292}
293
294/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100295 * Detach without Attach
296 * SM procedures without attach / RAU
297 * ATTACH / RAU
298 ** with / without authentication
299 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100300 * re-transmissions of LLC frames
301 * PDP Context activation
302 ** with different GGSN config in SGSN VTY
303 ** with different PDP context type (v4/v6/v46)
304 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100305 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100306 */
307
308testcase TC_wait_ns_up() runs on test_CT {
309 f_init();
310 f_sleep(20.0);
311}
312
Harald Welte5ac31492018-02-15 20:39:13 +0100313altstep as_mm_identity() runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100314 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welte5ac31492018-02-15 20:39:13 +0100315 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
316 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
317 BSSGP.send(ts_GMM_ID_RESP(mi));
318 repeat;
319 }
320 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
321 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
322 BSSGP.send(ts_GMM_ID_RESP(mi));
323 repeat;
324 }
325}
Harald Welte96a33b02018-02-04 10:36:22 +0100326
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200327/* perform GMM authentication (if expected).
328 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
329 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
330function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100331 var BssgpDecoded bd;
332 var PDU_L3_MS_SGSN l3_mo;
333 var PDU_L3_SGSN_MS l3_mt;
334 var default di := activate(as_mm_identity());
335 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200336 var GSUP_IE auth_tuple;
337 var template AuthenticationParameterAUTNTLV autn;
338
339 if (umts_aka_challenge) {
340 g_pars.vec := f_gen_auth_vec_3g();
341 autn := {
342 elementIdentifier := '28'O,
343 lengthIndicator := lengthof(g_pars.vec.autn),
344 autnValue := g_pars.vec.autn
345 };
346
347 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
348 g_pars.vec.sres,
349 g_pars.vec.kc,
350 g_pars.vec.ik,
351 g_pars.vec.ck,
352 g_pars.vec.autn,
353 g_pars.vec.res));
354 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
355 } else {
356 g_pars.vec := f_gen_auth_vec_2g();
357 autn := omit;
358 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
359 g_pars.vec.sres,
360 g_pars.vec.kc));
361 log("GSUP sends only 2G auth tuple", auth_tuple);
362 }
Harald Welte5ac31492018-02-15 20:39:13 +0100363 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
364 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200365
366 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
367 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
368 BSSGP.receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
Harald Welte5ac31492018-02-15 20:39:13 +0100369 l3_mt := bd.l3_mt;
370 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200371 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
372
373 if (umts_aka_challenge and not force_gsm_sres) {
374 /* set UMTS response instead */
375 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
376 valueField := substr(g_pars.vec.res, 0, 4)
377 };
378 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
379 elementIdentifier := '21'O,
380 lengthIndicator := lengthof(g_pars.vec.res) - 4,
381 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
382 };
383 }
384
385 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100386 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
387 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
388 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
389 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
390 }
391 BSSGP.send(l3_mo);
Harald Welte76dee092018-02-16 22:12:59 +0100392 } else {
393 /* wait for identity procedure */
394 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100395 }
Harald Welte76dee092018-02-16 22:12:59 +0100396
Harald Welte5ac31492018-02-15 20:39:13 +0100397 deactivate(di);
398}
399
Harald Weltef70997d2018-02-17 10:11:19 +0100400function f_upd_ptmsi_and_tlli(OCT4 p_tmsi) runs on BSSGP_ConnHdlr {
401 g_pars.p_tmsi := p_tmsi;
402 /* update TLLI */
403 g_pars.tlli_old := g_pars.tlli;
404 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
405 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli);
406}
407
Harald Welte04683d02018-02-16 22:43:45 +0100408function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
409 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100410 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
411 if (not (g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc == aa_plmn)) {
412 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
413 & "; expected " & hex2str(g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200414 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100415 }
Harald Welte04683d02018-02-16 22:43:45 +0100416 g_pars.ra := aa.routingAreaIdentification;
417 if (ispresent(aa.allocatedPTMSI)) {
418 if (not g_pars.net.expect_ptmsi) {
419 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200420 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100421 }
Harald Weltef70997d2018-02-17 10:11:19 +0100422 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100423 }
424 if (ispresent(aa.msIdentity)) {
425 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200426 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100427 }
428 /* P-TMSI.sig */
429 if (ispresent(aa.ptmsiSignature)) {
430 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
431 }
432 /* updateTimer */
433 // aa.readyTimer
434 /* T3302, T3319, T3323, T3312_ext, T3324 */
435}
436
Harald Welte91636de2018-02-17 10:16:14 +0100437function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra) runs on BSSGP_ConnHdlr {
438 /* mandatory IE */
439 g_pars.ra := ra.routingAreaId;
440 if (ispresent(ra.allocatedPTMSI)) {
441 if (not g_pars.net.expect_ptmsi) {
442 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200443 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100444 }
445 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
446 }
447 if (ispresent(ra.msIdentity)) {
448 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200449 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100450 }
451 /* P-TMSI.sig */
452 if (ispresent(ra.ptmsiSignature)) {
453 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
454 }
455 /* updateTimer */
456 // aa.readyTimer
457 /* T3302, T3319, T3323, T3312_ext, T3324 */
458}
459
460
Harald Welte5a4fa042018-02-16 20:59:21 +0100461function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
462 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
463}
464
Harald Welte23178c52018-02-17 09:36:33 +0100465/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100466private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100467 if (ispresent(g_pars.p_tmsi)) {
468 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
469 } else {
470 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
471 }
472}
473
Harald Welte311ec272018-02-17 09:40:03 +0100474private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100475 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100476 /* Expect MSC to perform LU with HLR */
477 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100478 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
479 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
480 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100481 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
482 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
483}
484
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200485private function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100486 var BssgpDecoded bd;
Harald Welte5a4fa042018-02-16 20:59:21 +0100487 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200488 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 +0100489
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200490 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
491 * 3G auth vectors */
492 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
493 /* The thing is, if the solSACapability is 'omit', then the
494 * revisionLevelIndicatior is at the wrong place! */
495 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
496
497 BSSGP.send(attach_req);
498 f_gmm_auth(umts_aka_challenge, force_gsm_sres);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200499 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100500 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100501
Harald Welte04683d02018-02-16 22:43:45 +0100502 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
503 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
504 }
505 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welte5ac31492018-02-15 20:39:13 +0100506 BSSGP.send(ts_GMM_ATTACH_COMPL);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200507}
508
509private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
510 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100511 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100512}
513
514testcase TC_attach() runs on test_CT {
515 var BSSGP_ConnHdlr vc_conn;
516 f_init();
517 f_sleep(1.0);
518 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1);
519 vc_conn.done;
520}
521
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100522testcase TC_attach_mnc3() runs on test_CT {
523 var BSSGP_ConnHdlr vc_conn;
524 f_init('023042'H);
525 f_sleep(1.0);
526 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1001);
527 vc_conn.done;
528}
529
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200530private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
531 f_gmm_attach(true, false);
532 setverdict(pass);
533}
534testcase TC_attach_umts_aka_umts_res() runs on test_CT {
535 var BSSGP_ConnHdlr vc_conn;
536 f_init();
537 f_sleep(1.0);
538 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb[0], 1002);
539 vc_conn.done;
540}
541
542private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
543 f_gmm_attach(true, true);
544 setverdict(pass);
545}
546testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
547 var BSSGP_ConnHdlr vc_conn;
548 f_init();
549 f_sleep(1.0);
550 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb[0], 1003);
551 vc_conn.done;
552}
553
Harald Welte5b7c8122018-02-16 21:48:17 +0100554/* MS never responds to ID REQ, expect ATTACH REJECT */
555private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100556 var RoutingAreaIdentificationV old_ra := f_random_RAI();
557
Harald Welte23178c52018-02-17 09:36:33 +0100558 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100559 alt {
Harald Welte1967d472018-02-16 21:54:21 +0100560 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100561 /* don't send ID Response */
562 repeat;
563 }
Harald Welte1967d472018-02-16 21:54:21 +0100564 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100565 setverdict(pass);
566 }
Harald Welte1967d472018-02-16 21:54:21 +0100567 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100568 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200569 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100570 }
571 }
572}
573testcase TC_attach_auth_id_timeout() runs on test_CT {
574 var BSSGP_ConnHdlr vc_conn;
575 f_init();
576 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb[0], 2, 40.0);
577 vc_conn.done;
578}
579
580/* HLR never responds to SAI REQ, expect ATTACH REJECT */
581private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100582 var RoutingAreaIdentificationV old_ra := f_random_RAI();
583
Harald Welte23178c52018-02-17 09:36:33 +0100584 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100585 alt {
586 [] as_mm_identity();
587 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
588 }
589 /* don't send SAI-response from HLR */
Harald Welte1967d472018-02-16 21:54:21 +0100590 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100591 setverdict(pass);
592}
593testcase TC_attach_auth_sai_timeout() runs on test_CT {
594 var BSSGP_ConnHdlr vc_conn;
595 f_init();
596 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb[0], 3);
597 vc_conn.done;
598}
599
Harald Weltefe253882018-02-17 09:25:00 +0100600/* HLR rejects SAI, expect ATTACH REJECT */
601private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100602 var RoutingAreaIdentificationV old_ra := f_random_RAI();
603
Harald Welte23178c52018-02-17 09:36:33 +0100604 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100605 alt {
606 [] as_mm_identity();
607 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
608 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
609 }
610 }
611 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
612 setverdict(pass);
613}
614testcase TC_attach_auth_sai_reject() runs on test_CT {
615 var BSSGP_ConnHdlr vc_conn;
616 f_init();
Harald Welteb7c14e92018-02-17 09:29:16 +0100617 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb[0], 4);
Harald Weltefe253882018-02-17 09:25:00 +0100618 vc_conn.done;
619}
620
Harald Welte5b7c8122018-02-16 21:48:17 +0100621/* HLR never responds to UL REQ, expect ATTACH REJECT */
622private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100623 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100624 var RoutingAreaIdentificationV old_ra := f_random_RAI();
625
Harald Welte23178c52018-02-17 09:36:33 +0100626 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100627 f_gmm_auth();
628 /* Expect MSC to perform LU with HLR */
629 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
630 /* Never follow-up with ISD_REQ or UL_RES */
631 alt {
Harald Welte1967d472018-02-16 21:54:21 +0100632 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100633 setverdict(pass);
634 }
Harald Welte04683d02018-02-16 22:43:45 +0100635 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
636 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100637 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200638 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100639 }
640 }
641}
642testcase TC_attach_gsup_lu_timeout() runs on test_CT {
643 var BSSGP_ConnHdlr vc_conn;
644 f_init();
645 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100646 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb[0], 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100647 vc_conn.done;
648}
649
Harald Welteb7c14e92018-02-17 09:29:16 +0100650/* HLR rejects UL REQ, expect ATTACH REJECT */
651private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
652 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100653 var RoutingAreaIdentificationV old_ra := f_random_RAI();
654
Harald Welte23178c52018-02-17 09:36:33 +0100655 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100656 f_gmm_auth();
657 /* Expect MSC to perform LU with HLR */
658 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
659 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
660 }
661 alt {
662 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
663 setverdict(pass);
664 }
665 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
666 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
667 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200668 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100669 }
670 }
671}
672testcase TC_attach_gsup_lu_reject() runs on test_CT {
673 var BSSGP_ConnHdlr vc_conn;
674 f_init();
675 f_sleep(1.0);
676 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb[0], 6);
677 vc_conn.done;
678}
679
680
Harald Welte3823e2e2018-02-16 21:53:48 +0100681/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
682private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100683 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100684 var RoutingAreaIdentificationV old_ra := f_random_RAI();
685
Harald Welte23178c52018-02-17 09:36:33 +0100686 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100687 f_gmm_auth();
688 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100689 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100690
Harald Welte04683d02018-02-16 22:43:45 +0100691 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
692 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
693 }
Harald Welte3823e2e2018-02-16 21:53:48 +0100694 BSSGP.send(ts_GMM_ATTACH_COMPL);
695 setverdict(pass);
696}
Harald Welte3823e2e2018-02-16 21:53:48 +0100697testcase TC_attach_combined() runs on test_CT {
698 var BSSGP_ConnHdlr vc_conn;
699 f_init();
700 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100701 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb[0], 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100702 vc_conn.done;
703}
704
Harald Welte76dee092018-02-16 22:12:59 +0100705/* Attempt of GPRS ATTACH in 'accept all' mode */
706private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100707 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100708 var RoutingAreaIdentificationV old_ra := f_random_RAI();
709
710 g_pars.net.expect_auth := false;
711
Harald Welte23178c52018-02-17 09:36:33 +0100712 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100713 f_gmm_auth();
Harald Welte04683d02018-02-16 22:43:45 +0100714 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
715 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
716 }
Harald Welte76dee092018-02-16 22:12:59 +0100717 BSSGP.send(ts_GMM_ATTACH_COMPL);
718 setverdict(pass);
719}
720testcase TC_attach_accept_all() runs on test_CT {
721 var BSSGP_ConnHdlr vc_conn;
722 f_init();
723 f_sleep(1.0);
724 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Harald Welteb7c14e92018-02-17 09:29:16 +0100725 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 8);
Harald Welte76dee092018-02-16 22:12:59 +0100726 vc_conn.done;
727}
Harald Welte5b7c8122018-02-16 21:48:17 +0100728
Harald Welteb2124b22018-02-16 22:26:56 +0100729/* Attempt of GPRS ATTACH in 'accept all' mode */
730private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100731 var RoutingAreaIdentificationV old_ra := f_random_RAI();
732
733 /* Simulate a foreign IMSI */
734 g_pars.imsi := '001010123456789'H;
735 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
736
737 g_pars.net.expect_auth := false;
738
Harald Welte23178c52018-02-17 09:36:33 +0100739 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100740 alt {
741 [] as_mm_identity();
742 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
743 setverdict(pass);
744 }
745 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
746 setverdict(pass);
747 }
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200748 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
749 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200750 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200751 }
Harald Welteb2124b22018-02-16 22:26:56 +0100752 }
753}
754testcase TC_attach_closed() runs on test_CT {
755 var BSSGP_ConnHdlr vc_conn;
756 f_init();
757 f_sleep(1.0);
758 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
759 /* test with foreign IMSI: Must Reject */
Harald Welteb7c14e92018-02-17 09:29:16 +0100760 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100761 vc_conn.done;
762 /* test with home IMSI: Must Accept */
Harald Welteb7c14e92018-02-17 09:29:16 +0100763 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100764 vc_conn.done;
765}
766
Harald Welte04683d02018-02-16 22:43:45 +0100767/* Routing Area Update from Unknown TLLI -> REJECT */
768private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100769 var RoutingAreaIdentificationV old_ra := f_random_RAI();
770
Harald Welte23178c52018-02-17 09:36:33 +0100771 BSSGP.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 +0100772 alt {
773 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
774 setverdict(pass);
775 }
776 /* FIXME: Expect XID RESET? */
777 [] BSSGP.receive { repeat; }
778 }
779}
780testcase TC_rau_unknown() runs on test_CT {
781 var BSSGP_ConnHdlr vc_conn;
782 f_init();
783 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100784 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb[0], 11);
Harald Welte04683d02018-02-16 22:43:45 +0100785 vc_conn.done;
786}
787
Harald Welte91636de2018-02-17 10:16:14 +0100788private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
789 var BssgpDecoded bd;
790
791 /* first perform regular attach */
792 f_TC_attach(id);
793
794 /* then send RAU */
795 BSSGP.send(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit));
796 alt {
797 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
798 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept);
Alexander Couzens80ec1ea2018-05-12 16:44:36 +0200799 BSSGP.send(ts_GMM_RAU_COMPL);
Harald Welte91636de2018-02-17 10:16:14 +0100800 setverdict(pass);
801 }
802 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
803 setverdict(fail, "Unexpected RAU Reject");
Daniel Willmannafce8662018-07-06 23:11:32 +0200804 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100805 }
806 [] BSSGP.receive { repeat; }
807 }
808}
809testcase TC_attach_rau() runs on test_CT {
810 var BSSGP_ConnHdlr vc_conn;
811 f_init();
812 f_sleep(1.0);
813 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb[0], 12);
814 vc_conn.done;
815}
Harald Welte04683d02018-02-16 22:43:45 +0100816
Harald Welte6abb9fe2018-02-17 15:24:48 +0100817/* general GPRS DETACH helper */
818function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge) runs on BSSGP_ConnHdlr {
819 var BssgpDecoded bd;
820 timer T := 5.0;
821 BSSGP.send(ts_GMM_DET_REQ_MO(detach_type, power_off));
822 if (expect_purge) {
823 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
824 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
825 }
826 T.start;
827 alt {
828 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
829 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200830 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100831 }
832 [power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
833 g_pars.ra := omit;
834 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200835 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100836 /* TODO: check if any PDP contexts are deactivated on network side? */
837 }
838 [power_off] T.timeout {
839 setverdict(pass);
840 }
841 [not power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
842 g_pars.ra := omit;
843 setverdict(pass);
844 /* TODO: check if any PDP contexts are deactivated on network side? */
845 }
846 [] BSSGP.receive { repeat; }
847 }
848}
849
850/* IMSI DETACH (non-power-off) for unknown TLLI */
851private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
852 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
853}
854testcase TC_detach_unknown_nopoweroff() runs on test_CT {
855 var BSSGP_ConnHdlr vc_conn;
856 f_init();
857 f_sleep(1.0);
858 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb[0], 13);
859 vc_conn.done;
860}
861
862/* IMSI DETACH (power-off) for unknown TLLI */
863private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
864 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
865}
866testcase TC_detach_unknown_poweroff() runs on test_CT {
867 var BSSGP_ConnHdlr vc_conn;
868 f_init();
869 f_sleep(1.0);
870 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb[0], 14);
871 vc_conn.done;
872}
873
874/* IMSI DETACH (non-power-off) for known TLLI */
875private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
876 /* first perform regular attach */
877 f_TC_attach(id);
878
879 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
880}
881testcase TC_detach_nopoweroff() runs on test_CT {
882 var BSSGP_ConnHdlr vc_conn;
883 f_init();
884 f_sleep(1.0);
885 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb[0], 15);
886 vc_conn.done;
887}
888
889/* IMSI DETACH (power-off) for known TLLI */
890private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
891 /* first perform regular attach */
892 f_TC_attach(id);
893
894 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
895}
896testcase TC_detach_poweroff() runs on test_CT {
897 var BSSGP_ConnHdlr vc_conn;
898 f_init();
899 f_sleep(1.0);
900 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb[0], 16);
901 vc_conn.done;
902}
903
Harald Welteeded9ad2018-02-17 20:57:34 +0100904type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100905 BIT3 tid, /* L3 Transaction ID */
906 BIT4 nsapi, /* SNDCP NSAPI */
907 BIT4 sapi, /* LLC SAPI */
908 QoSV qos, /* QoS parameters */
909 PDPAddressV addr, /* IP address */
910 octetstring apn optional, /* APN name */
911 ProtocolConfigOptionsV pco optional, /* protoco config opts */
912 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100913 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100914 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100915
Harald Welte822f9102018-02-18 20:39:06 +0100916 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
917 OCT4 ggsn_tei_u, /* GGSN TEI User */
918 octetstring ggsn_ip_c, /* GGSN IP Control */
919 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200920 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100921
Harald Welte822f9102018-02-18 20:39:06 +0100922 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
923 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
924 octetstring sgsn_ip_c optional, /* SGSN IP Control */
925 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100926};
927
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100928
929private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
930 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
931 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
932 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
933 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
934 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
935 f_gtp_register_teid(apars.ggsn_tei_c);
936 f_gtp_register_teid(apars.ggsn_tei_u);
937}
938
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200939function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100940 var boolean exp_rej := ispresent(apars.exp_rej_cause);
941 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200942 var template Recovery_gtpc recovery := omit;
943
944 if (send_recovery) {
945 recovery := ts_Recovery(apars.ggsn_restart_ctr);
946 }
Harald Welteeded9ad2018-02-17 20:57:34 +0100947
948 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
949 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100950 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
951 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
952 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
953 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
954 apars.sgsn_tei_c, apars.gtp_resp_cause,
955 apars.ggsn_tei_c, apars.ggsn_tei_u,
956 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200957 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
958 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +0100959 }
960 alt {
Harald Welte28307082018-02-18 12:14:18 +0100961 [exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100962 setverdict(pass);
963 }
Harald Welte28307082018-02-18 12:14:18 +0100964 [exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100965 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +0200966 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +0100967 }
Harald Welte28307082018-02-18 12:14:18 +0100968 [not exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100969 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +0200970 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +0100971 }
Harald Welte28307082018-02-18 12:14:18 +0100972 [not exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100973 setverdict(pass);
974 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100975 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +0100976 }
977}
978
Harald Welte6f203162018-02-18 22:04:55 +0100979function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
980 var boolean exp_rej := ispresent(apars.exp_rej_cause);
981 var Gtp1cUnitdata g_ud;
982
983 BSSGP.send(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
984 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
985 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
986 BSSGP.clear;
987 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
988 }
989 alt {
990 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
991 setverdict(pass);
992 }
993 [] as_xid(apars);
994 }
995}
996
Pau Espin Pedrol482dde62018-07-18 13:47:42 +0200997function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +0100998 var Gtp1cUnitdata g_ud;
999 var integer seq_nr := 23;
1000 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1001
1002 BSSGP.clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001003 if (error_ind) {
1004 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1005 } else {
1006 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1007 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001008
1009 timer T := 5.0;
1010 T.start;
1011
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001012 alt {
Pau Espin Pedrolbcddb8c2018-07-16 12:28:03 +02001013 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001014 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1015 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001016 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1017 repeat;
1018 }
1019 [] T.timeout {
1020 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1021 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001022 }
1023}
1024
Harald Welte6f203162018-02-18 22:04:55 +01001025
Harald Welteeded9ad2018-02-17 20:57:34 +01001026/* Table 10.5.156/3GPP TS 24.008 */
1027template (value) QoSV t_QosDefault := {
1028 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1029 delayClass := '100'B, /* best effort */
1030 spare1 := '00'B,
1031 precedenceClass := '010'B, /* normal */
1032 spare2 := '0'B,
1033 peakThroughput := '0000'B, /* subscribed */
1034 meanThroughput := '00000'B, /* subscribed */
1035 spare3 := '000'B,
1036 deliverErroneusSDU := omit,
1037 deliveryOrder := omit,
1038 trafficClass := omit,
1039 maxSDUSize := omit,
1040 maxBitrateUplink := omit,
1041 maxBitrateDownlink := omit,
1042 sduErrorRatio := omit,
1043 residualBER := omit,
1044 trafficHandlingPriority := omit,
1045 transferDelay := omit,
1046 guaranteedBitRateUplink := omit,
1047 guaranteedBitRateDownlink := omit,
1048 sourceStatisticsDescriptor := omit,
1049 signallingIndication := omit,
1050 spare4 := omit,
1051 maxBitrateDownlinkExt := omit,
1052 guaranteedBitRateDownlinkExt := omit,
1053 maxBitrateUplinkExt := omit,
1054 guaranteedBitRateUplinkExt := omit,
1055 maxBitrateDownlinkExt2 := omit,
1056 guaranteedBitRateDownlinkExt2 := omit,
1057 maxBitrateUplinkExt2 := omit,
1058 guaranteedBitRateUplinkExt2 := omit
1059}
1060
1061/* 10.5.6.4 / 3GPP TS 24.008 */
1062template (value) PDPAddressV t_AddrIPv4dyn := {
1063 pdpTypeOrg := '0001'B, /* IETF */
1064 spare := '0000'B,
1065 pdpTypeNum := '21'O, /* IPv4 */
1066 addressInfo := omit
1067}
1068template (value) PDPAddressV t_AddrIPv6dyn := {
1069 pdpTypeOrg := '0001'B, /* IETF */
1070 spare := '0000'B,
1071 pdpTypeNum := '53'O, /* IPv6 */
1072 addressInfo := omit
1073}
1074
Harald Welte37692d82018-02-18 15:21:34 +01001075template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001076 tid := '000'B,
1077 nsapi := '0101'B, /* < 5 are reserved */
1078 sapi := '0011'B, /* 3/5/9/11 */
1079 qos := t_QosDefault,
1080 addr := t_AddrIPv4dyn,
1081 apn := omit,
1082 pco := omit,
1083 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001084 gtp_resp_cause := int2oct(128, 1),
1085 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001086
1087 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001088 ggsn_tei_c := f_rnd_octstring(4),
1089 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001090 ggsn_ip_c := f_inet_addr(ggsn_ip),
1091 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001092 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001093
Harald Welteeded9ad2018-02-17 20:57:34 +01001094 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001095 sgsn_tei_u := omit,
1096 sgsn_ip_c := omit,
1097 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001098}
1099
Harald Welte37692d82018-02-18 15:21:34 +01001100template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1101 connId := 1,
1102 remName := f_inet_ntoa(ip),
1103 remPort := GTP1U_PORT
1104}
1105
1106template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1107 connId := 1,
1108 remName := f_inet_ntoa(ip),
1109 remPort := GTP1C_PORT
1110}
1111
1112private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1113 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1114 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1115}
1116
1117private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
1118 [] BSSGP.receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
1119 repeat;
1120 }
1121}
1122
1123template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1124 pDU_SN_UNITDATA := {
1125 nsapi := nsapi,
1126 moreBit := ?,
1127 snPduType := '1'B,
1128 firstSegmentIndicator := ?,
1129 spareBit := ?,
1130 pcomp := ?,
1131 dcomp := ?,
1132 npduNumber := ?,
1133 segmentNumber := ?,
1134 npduNumberContinued := ?,
1135 dataSegmentSnUnitdataPdu := payload
1136 }
1137}
1138
1139/* simple case: single segment, no compression */
1140template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1141 pDU_SN_UNITDATA := {
1142 nsapi := nsapi,
1143 moreBit := '0'B,
1144 snPduType := '1'B,
1145 firstSegmentIndicator := '1'B,
1146 spareBit := '0'B,
1147 pcomp := '0000'B,
1148 dcomp := '0000'B,
1149 npduNumber := '0000'B,
1150 segmentNumber := '0000'B,
1151 npduNumberContinued := '00'O,
1152 dataSegmentSnUnitdataPdu := payload
1153 }
1154}
1155
1156/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1157private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1158 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1159 f_gtpu_send(apars, payload);
1160 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1161 alt {
1162 [] as_xid(apars);
1163 [] BSSGP.receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1164 }
1165}
1166
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001167/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001168private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1169 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1170 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1171 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
1172 BSSGP.send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001173 /* Expect PDU via GTP from SGSN on simulated GGSN */
1174 alt {
1175 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1176 }
1177}
1178
Harald Welteeded9ad2018-02-17 20:57:34 +01001179private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001180 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001181
1182 /* first perform regular attach */
1183 f_TC_attach(id);
1184
1185 f_pdp_ctx_act(apars);
1186}
1187testcase TC_attach_pdp_act() runs on test_CT {
1188 var BSSGP_ConnHdlr vc_conn;
1189 f_init();
1190 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1191 vc_conn.done;
1192}
Harald Welteb2124b22018-02-16 22:26:56 +01001193
Harald Welte835b15f2018-02-18 14:39:11 +01001194/* PDP Context activation for not-attached subscriber; expect fail */
1195private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001196 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welte835b15f2018-02-18 14:39:11 +01001197 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1198 apars.apn, apars.pco));
1199 alt {
1200 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
1201 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
1202 setverdict(pass);
1203 }
1204 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1205 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001206 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001207 }
1208 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
1209 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001210 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001211 }
1212 [] BSSGP.receive { repeat; }
1213 }
1214}
1215testcase TC_pdp_act_unattached() runs on test_CT {
1216 var BSSGP_ConnHdlr vc_conn;
1217 f_init();
1218 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1219 vc_conn.done;
1220}
1221
Harald Welte37692d82018-02-18 15:21:34 +01001222/* ATTACH + PDP CTX ACT + user plane traffic */
1223private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1224 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1225
1226 /* first perform regular attach */
1227 f_TC_attach(id);
1228 /* then activate PDP context */
1229 f_pdp_ctx_act(apars);
1230 /* then transceive a downlink PDU */
1231 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1232 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1233}
1234testcase TC_attach_pdp_act_user() runs on test_CT {
1235 var BSSGP_ConnHdlr vc_conn;
1236 f_init();
1237 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1238 vc_conn.done;
1239}
1240
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001241/* ATTACH + PDP CTX ACT; reject from GGSN */
1242private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1243 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1244
1245 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1246 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1247
1248 /* first perform regular attach */
1249 f_TC_attach(id);
1250 /* then activate PDP context */
1251 f_pdp_ctx_act(apars);
1252}
1253testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1254 var BSSGP_ConnHdlr vc_conn;
1255 f_init();
1256 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1257 vc_conn.done;
1258}
Harald Welte835b15f2018-02-18 14:39:11 +01001259
Harald Welte6f203162018-02-18 22:04:55 +01001260/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1261private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1262 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1263
1264 /* first perform regular attach */
1265 f_TC_attach(id);
1266 /* then activate PDP context */
1267 f_pdp_ctx_act(apars);
1268 /* then transceive a downlink PDU */
1269 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1270 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1271
1272 f_pdp_ctx_deact_mo(apars, '00'O);
1273}
1274testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1275 var BSSGP_ConnHdlr vc_conn;
1276 f_init();
1277 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1278 vc_conn.done;
1279}
1280
Harald Welte57b9b7f2018-02-18 22:28:13 +01001281/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1282private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1283 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1284
1285 /* first perform regular attach */
1286 f_TC_attach(id);
1287 /* then activate PDP context */
1288 f_pdp_ctx_act(apars);
1289 /* then transceive a downlink PDU */
1290 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1291 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1292
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001293 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001294}
1295testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1296 var BSSGP_ConnHdlr vc_conn;
1297 f_init();
1298 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1299 vc_conn.done;
1300}
1301
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001302/* ATTACH + ATTACH (2nd) */
1303private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1304 g_pars.t_guard := 5.0;
1305
1306 /* first perform regular attach */
1307 f_TC_attach(id);
1308
1309 /* second to perform regular attach */
1310 f_TC_attach(id);
1311}
1312
1313
1314testcase TC_attach_second_attempt() runs on test_CT {
1315 var BSSGP_ConnHdlr vc_conn;
1316 f_init();
1317 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1318 vc_conn.done;
1319}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001320
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001321private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001322 var Gtp1cUnitdata g_ud;
1323 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1324
1325 /* first perform regular attach */
1326 f_TC_attach(id);
1327 /* Activate a pdp context against the GGSN */
1328 f_pdp_ctx_act(apars);
1329 /* Wait to receive first echo request and send initial Restart counter */
1330 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1331 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1332 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1333 }
1334 /* Wait to receive second echo request and send incremented Restart
1335 counter. This will fake a restarted GGSN, and pdp ctx allocated
1336 should be released by SGSN */
1337 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1338 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1339 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1340 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1341 }
1342 var OCT1 cause_network_failure := int2oct(38, 1)
1343 alt {
1344 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
1345 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1346 setverdict(pass);
1347 }
1348 [] as_xid(apars);
1349 }
1350 setverdict(pass);
1351}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001352/* ATTACH + trigger Recovery procedure through EchoResp */
1353testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001354 var BSSGP_ConnHdlr vc_conn;
1355 g_use_echo := true
1356 f_init();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001357 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 +02001358 vc_conn.done;
1359 g_use_echo := false
1360}
1361
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001362private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1363 var Gtp1cUnitdata g_ud;
1364 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1365 var integer seq_nr := 23;
1366 var GtpPeer peer;
1367 /* first perform regular attach */
1368 f_TC_attach(id);
1369
1370 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1371 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1372 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1373 f_pdp_ctx_act(apars, true);
1374
1375 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1376/* received. */
1377 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1378
1379 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1380 would be great to have an active pdp context here before triggering
1381 Recovery, and making sure the the DEACT request is sent by the SGSN.
1382 */
1383
1384 /* Activate a pdp context against the GGSN, send incremented Recovery
1385 IE. This should trigger the recovery path, but still this specific
1386 CTX activation should work. */
1387 apars.exp_rej_cause := omit; /* default value for tests */
1388 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1389 f_pdp_ctx_act(apars, true);
1390
1391 setverdict(pass);
1392}
1393/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1394testcase TC_attach_restart_ctr_create() runs on test_CT {
1395 var BSSGP_ConnHdlr vc_conn;
1396 f_init();
1397 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb[0], 24, 30.0);
1398 vc_conn.done;
1399}
1400
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001401/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1402private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1403 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1404 var integer seq_nr := 23;
1405 var GtpPeer peer;
1406 var integer i;
1407
1408 /* first perform regular attach */
1409 f_TC_attach(id);
1410 /* then activate PDP context */
1411 f_pdp_ctx_act(apars);
1412
1413 BSSGP.clear;
1414 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1415 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1416
1417 for (i := 0; i < 5; i := i+1) {
1418 alt {
1419 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
1420 [] as_xid(apars);
1421 }
1422 }
1423
1424 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1425
1426 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1427 setverdict(pass);
1428}
1429testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1430 var BSSGP_ConnHdlr vc_conn;
1431 f_init();
1432 f_sleep(1.0);
1433 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb[0], 25, 60.0);
1434 vc_conn.done;
1435}
1436
Alexander Couzens5e307b42018-05-22 18:12:20 +02001437private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1438 /* MS: perform regular attach */
1439 f_TC_attach(id);
1440
1441 /* HLR: cancel the location request */
1442 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1443 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001444
1445 /* ensure no Detach Request got received */
1446 timer T := 5.0;
1447 T.start;
1448 alt {
1449 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
1450 T.stop;
1451 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001452 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001453 }
1454 [] T.timeout {
1455 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001456 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001457 }
1458 [] BSSGP.receive {
1459 repeat;
1460 }
1461 }
1462}
1463
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001464/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1465private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1466 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1467
1468 /* first perform regular attach */
1469 f_TC_attach(id);
1470 /* then activate PDP context */
1471 f_pdp_ctx_act(apars);
1472 /* then transceive a downlink PDU */
1473 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1474
1475 /* Send Error indication as response from upload PDU and expect deact towards MS */
1476 f_pdp_ctx_deact_mt(apars, true);
1477}
1478testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1479 var BSSGP_ConnHdlr vc_conn;
1480 f_init();
1481 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb[0], 26);
1482 vc_conn.done;
1483}
1484
Alexander Couzens5e307b42018-05-22 18:12:20 +02001485testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1486 /* MS <-> SGSN: GMM Attach
1487 * HLR -> SGSN: Cancel Location Request
1488 * HLR <- SGSN: Cancel Location Ack
1489 */
1490 var BSSGP_ConnHdlr vc_conn;
1491 f_init();
1492 f_sleep(1.0);
1493 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1494 vc_conn.done;
1495}
1496
1497
Alexander Couzensc87967a2018-05-22 16:09:54 +02001498private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1499 /* MS: perform regular attach */
1500 f_TC_attach(id);
1501
1502 /* HLR: cancel the location request */
1503 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1504 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1505 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1506
1507 /* MS: receive a Detach Request */
1508 BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1509 BSSGP.send(ts_GMM_DET_ACCEPT_MO);
1510
1511 setverdict(pass);
1512}
1513
1514testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1515 /* MS <-> SGSN: GMM Attach
1516 * HLR -> SGSN: Cancel Location Request
1517 * HLR <- SGSN: Cancel Location Ack
1518 * MS <- SGSN: Detach Request
1519 * SGSN-> MS: Detach Complete
1520 */
1521 var BSSGP_ConnHdlr vc_conn;
1522 f_init();
1523 f_sleep(1.0);
1524 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1525 vc_conn.done;
1526}
1527
1528
Alexander Couzens6c47f292018-05-22 17:09:49 +02001529private function f_hlr_location_cancel_request_unknown_subscriber(
1530 charstring id,
1531 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1532
1533 /* HLR: cancel the location request */
1534 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1535
1536 /* cause 2 = IMSI_UNKNOWN */
1537 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1538
1539 setverdict(pass);
1540}
1541
1542private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001543 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001544}
1545
1546testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1547 /* HLR -> SGSN: Cancel Location Request
1548 * HLR <- SGSN: Cancel Location Error
1549 */
1550
1551 var BSSGP_ConnHdlr vc_conn;
1552 f_init();
1553 f_sleep(1.0);
1554 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1555 vc_conn.done;
1556}
1557
1558private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001559 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001560}
1561
1562testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1563 /* HLR -> SGSN: Cancel Location Request
1564 * HLR <- SGSN: Cancel Location Error
1565 */
1566
1567 var BSSGP_ConnHdlr vc_conn;
1568 f_init();
1569 f_sleep(1.0);
1570 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1571 vc_conn.done;
1572}
1573
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001574private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1575 f_TC_attach(id);
1576 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1577}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001578
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001579testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1580 /* MS <-> SGSN: Attach
1581 * MS -> SGSN: Detach Req (Power off)
1582 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1583 */
1584 var BSSGP_ConnHdlr vc_conn;
1585 var integer id := 33;
1586 var charstring imsi := hex2str(f_gen_imsi(id));
1587
1588 f_init();
1589 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb[0], id);
1590 vc_conn.done;
1591
1592 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1593}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001594
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001595/* Attempt an attach, but loose the Identification Request (IMEI) */
1596private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1597 var integer count_req := 0;
1598 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1599
1600 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1601
1602 alt {
1603 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1604 /* break */
1605 }
1606 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1607 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1608 BSSGP.send(ts_GMM_ID_RESP(mi));
1609 repeat;
1610 }
1611 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1612 /* ignore ID REQ IMEI */
1613 count_req := count_req + 1;
1614 repeat;
1615 }
1616 }
1617 if (count_req != 5) {
1618 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001619 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001620 }
1621 setverdict(pass);
1622}
1623
1624testcase TC_attach_no_imei_response() runs on test_CT {
1625 /* MS -> SGSN: Attach Request IMSI
1626 * MS <- SGSN: Identity Request IMSI (optional)
1627 * MS -> SGSN: Identity Response IMSI (optional)
1628 * MS <- SGSN: Identity Request IMEI
1629 * MS -x SGSN: no response
1630 * MS <- SGSN: re-send: Identity Request IMEI 4x
1631 * MS <- SGSN: Attach Reject
1632 */
1633 var BSSGP_ConnHdlr vc_conn;
1634 f_init();
1635 f_sleep(1.0);
1636 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1637 vc_conn.done;
1638}
1639
Alexander Couzens53f20562018-06-12 16:24:12 +02001640/* Attempt an attach, but loose the Identification Request (IMSI) */
1641private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1642 var integer count_req := 0;
1643 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1644
1645 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1646 g_pars.p_tmsi := 'c0000035'O;
1647
1648 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1649
1650 alt {
1651 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1652 /* break */
1653 }
1654 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1655 /* ignore ID REQ IMSI */
1656 count_req := count_req + 1;
1657 repeat;
1658 }
1659 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1660 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1661 BSSGP.send(ts_GMM_ID_RESP(mi));
1662 repeat;
1663 }
1664 }
1665 if (count_req != 5) {
1666 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001667 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001668 }
1669 setverdict(pass);
1670}
1671
1672testcase TC_attach_no_imsi_response() runs on test_CT {
1673 /* MS -> SGSN: Attach Request TMSI (unknown)
1674 * MS <- SGSN: Identity Request IMEI (optional)
1675 * MS -> SGSN: Identity Response IMEI (optional)
1676 * MS <- SGSN: Identity Request IMSI
1677 * MS -x SGSN: no response
1678 * MS <- SGSN: re-send: Identity Request IMSI 4x
1679 * MS <- SGSN: Attach Reject
1680 */
1681 var BSSGP_ConnHdlr vc_conn;
1682 f_init();
1683 f_sleep(1.0);
1684 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1685 vc_conn.done;
1686}
1687
Alexander Couzenscf818962018-06-05 18:00:00 +02001688private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1689 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1690}
1691
1692testcase TC_attach_check_subscriber_list() runs on test_CT {
1693 /* MS <-> SGSN: Attach
1694 * VTY -> SGSN: Check if MS is in subscriber cache
1695 */
1696 var BSSGP_ConnHdlr vc_conn;
1697 var integer id := 34;
1698 var charstring imsi := hex2str(f_gen_imsi(id));
1699
1700 f_init();
1701 f_sleep(1.0);
1702 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], id);
1703 vc_conn.done;
1704
1705 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1706 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1707}
1708
Alexander Couzensf9858652018-06-07 16:14:53 +02001709private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1710 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1711 var BssgpDecoded bd;
1712
1713 /* unregister the old IMSI */
1714 f_bssgp_client_unregister(g_pars.imsi);
1715 /* Simulate a foreign IMSI */
1716 g_pars.imsi := '001010123456789'H;
1717 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
1718
1719 /* there is no auth */
1720 g_pars.net.expect_auth := false;
1721
1722 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
1723 f_gmm_auth();
1724 alt {
1725 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1726 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001727 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001728 }
1729 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
1730 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1731 BSSGP.send(ts_GMM_ATTACH_COMPL);
1732 setverdict(pass);
1733 }
1734 }
1735}
1736testcase TC_attach_closed_add_vty() runs on test_CT {
1737 /* VTY-> SGSN: policy close
1738 * MS -> SGSN: Attach Request
1739 * MS <- SGSN: Identity Request IMSI
1740 * MS -> SGSN: Identity Response IMSI
1741 * MS <- SGSN: Attach Reject
1742 * VTY-> SGSN: policy imsi-acl add IMSI
1743 * MS -> SGSN: Attach Request
1744 * MS <- SGSN: Identity Request IMSI
1745 * MS -> SGSN: Identity Response IMSI
1746 * MS <- SGSN: Identity Request IMEI
1747 * MS -> SGSN: Identity Response IMEI
1748 * MS <- SGSN: Attach Accept
1749 */
1750 var BSSGP_ConnHdlr vc_conn;
1751 f_init();
1752 f_sleep(1.0);
1753 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1754 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
1755 /* test with foreign IMSI: Must Reject */
1756 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
1757 vc_conn.done;
1758 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456789");
1759 /* test with same IMSI: Must Accept */
1760 vc_conn := f_start_handler(refers(f_TC_attach_closed_imsi_added), testcasename(), g_gb[0], 10);
1761 vc_conn.done;
1762}
1763
Alexander Couzens0085bd72018-06-12 19:08:44 +02001764/* Attempt an attach, but never answer a Attach Complete */
1765private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1766 var integer count_req := 0;
1767
1768 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1769 f_gmm_auth();
1770
1771 alt {
1772 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1773 /* break */
1774 }
1775 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
1776 /* ignore */
1777 count_req := count_req + 1;
1778 repeat;
1779 }
1780 }
1781 if (count_req != 5) {
1782 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001783 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001784 }
1785 setverdict(pass);
1786}
1787
1788testcase TC_attach_check_complete_resend() runs on test_CT {
1789 /* MS -> SGSN: Attach Request IMSI
1790 * MS <- SGSN: Identity Request *
1791 * MS -> SGSN: Identity Response *
1792 * MS <- SGSN: Attach Complete 5x
1793 */
1794 var BSSGP_ConnHdlr vc_conn;
1795 f_init();
1796 f_sleep(1.0);
1797 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb[0], 36, 60.0);
1798 vc_conn.done;
1799}
1800
Harald Welte5ac31492018-02-15 20:39:13 +01001801control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001802 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001803 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001804 execute( TC_attach_umts_aka_umts_res() );
1805 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001806 execute( TC_attach_auth_id_timeout() );
1807 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001808 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001809 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001810 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001811 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001812 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001813 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001814 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001815 execute( TC_attach_no_imsi_response() );
Alexander Couzensf9858652018-06-07 16:14:53 +02001816 execute( TC_attach_closed_add_vty(), 10.0 );
Alexander Couzenscf818962018-06-05 18:00:00 +02001817 execute( TC_attach_check_subscriber_list(), 10.0 );
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001818 execute( TC_attach_detach_check_subscriber_list(), 10.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02001819 execute( TC_attach_check_complete_resend() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001820 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001821 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1822 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1823 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001824 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001825 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001826 execute( TC_detach_unknown_nopoweroff() );
1827 execute( TC_detach_unknown_poweroff() );
1828 execute( TC_detach_nopoweroff() );
1829 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001830 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001831 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001832 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001833 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001834 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001835 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001836 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001837 execute( TC_attach_restart_ctr_echo() );
1838 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001839 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001840 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Harald Welte5ac31492018-02-15 20:39:13 +01001841}
Harald Welte96a33b02018-02-04 10:36:22 +01001842
1843
1844
1845}