blob: d7e956fec39c413abf85da1874d6a411a89de038 [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");
137 self.stop;
138 }
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 };
Harald Welte96a33b02018-02-04 10:36:22 +0100191
Harald Welte3fdbe822018-02-18 19:10:18 +0100192 f_init_gb(g_gb[0], "SGSN_Test-Gb0");
Harald Welte5ac31492018-02-15 20:39:13 +0100193 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100194 f_init_gtp("SGSN_Test");
Harald Weltebd194722018-02-16 22:11:08 +0100195 f_init_vty();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200196 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100197}
Harald Welte96a33b02018-02-04 10:36:22 +0100198
Harald Welte5ac31492018-02-15 20:39:13 +0100199type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
200
201/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte62e29582018-02-16 21:17:11 +0100202function f_start_handler(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix,
203 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100204runs on test_CT return BSSGP_ConnHdlr {
205 var BSSGP_ConnHdlr vc_conn;
206 var SGSN_ConnHdlrNetworkPars net_pars := {
207 expect_ptmsi := true,
208 expect_auth := true,
209 expect_ciph := false
210 };
211 var BSSGP_ConnHdlrPars pars := {
212 imei := f_gen_imei(imsi_suffix),
213 imsi := f_gen_imsi(imsi_suffix),
214 msisdn := f_gen_msisdn(imsi_suffix),
215 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100216 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100217 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100218 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100219 ra := omit,
220 bssgp_cell_id := gb.cfg.cell_id,
221 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100222 net := net_pars,
223 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100224 };
225
226 vc_conn := BSSGP_ConnHdlr.create(id);
227 connect(vc_conn:BSSGP, gb.vc_BSSGP:BSSGP_SP);
228 connect(vc_conn:BSSGP_PROC, gb.vc_BSSGP:BSSGP_PROC);
229
230 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
231 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
232
Harald Welteeded9ad2018-02-17 20:57:34 +0100233 connect(vc_conn:GTP, vc_GTP:CLIENT);
234 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
235
Harald Welte5ac31492018-02-15 20:39:13 +0100236 vc_conn.start(f_handler_init(fn, id, pars));
237 return vc_conn;
238}
239
Harald Welte62e29582018-02-16 21:17:11 +0100240private altstep as_Tguard() runs on BSSGP_ConnHdlr {
241 [] g_Tguard.timeout {
242 setverdict(fail, "Tguard timeout");
243 self.stop;
244 }
245}
246
Harald Welte5ac31492018-02-15 20:39:13 +0100247/* first function called in every ConnHdlr */
248private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
249runs on BSSGP_ConnHdlr {
250 /* do some common stuff like setting up g_pars */
251 g_pars := pars;
252
253 /* register with BSSGP core */
254 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
255 /* tell GSUP dispatcher to send this IMSI to us */
256 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100257 /* tell GTP dispatcher to send this IMSI to us */
258 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100259
Harald Welte62e29582018-02-16 21:17:11 +0100260 g_Tguard.start(pars.t_guard);
261 activate(as_Tguard());
262
Harald Welte5ac31492018-02-15 20:39:13 +0100263 /* call the user-supplied test case function */
264 fn.apply(id);
265 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100266}
267
268/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100269 * Detach without Attach
270 * SM procedures without attach / RAU
271 * ATTACH / RAU
272 ** with / without authentication
273 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100274 * re-transmissions of LLC frames
275 * PDP Context activation
276 ** with different GGSN config in SGSN VTY
277 ** with different PDP context type (v4/v6/v46)
278 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100279 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100280 */
281
282testcase TC_wait_ns_up() runs on test_CT {
283 f_init();
284 f_sleep(20.0);
285}
286
Harald Welte5ac31492018-02-15 20:39:13 +0100287altstep as_mm_identity() runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100288 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welte5ac31492018-02-15 20:39:13 +0100289 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
290 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
291 BSSGP.send(ts_GMM_ID_RESP(mi));
292 repeat;
293 }
294 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
295 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
296 BSSGP.send(ts_GMM_ID_RESP(mi));
297 repeat;
298 }
299}
Harald Welte96a33b02018-02-04 10:36:22 +0100300
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200301/* perform GMM authentication (if expected).
302 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
303 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
304function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100305 var BssgpDecoded bd;
306 var PDU_L3_MS_SGSN l3_mo;
307 var PDU_L3_SGSN_MS l3_mt;
308 var default di := activate(as_mm_identity());
309 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200310 var GSUP_IE auth_tuple;
311 var template AuthenticationParameterAUTNTLV autn;
312
313 if (umts_aka_challenge) {
314 g_pars.vec := f_gen_auth_vec_3g();
315 autn := {
316 elementIdentifier := '28'O,
317 lengthIndicator := lengthof(g_pars.vec.autn),
318 autnValue := g_pars.vec.autn
319 };
320
321 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
322 g_pars.vec.sres,
323 g_pars.vec.kc,
324 g_pars.vec.ik,
325 g_pars.vec.ck,
326 g_pars.vec.autn,
327 g_pars.vec.res));
328 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
329 } else {
330 g_pars.vec := f_gen_auth_vec_2g();
331 autn := omit;
332 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
333 g_pars.vec.sres,
334 g_pars.vec.kc));
335 log("GSUP sends only 2G auth tuple", auth_tuple);
336 }
Harald Welte5ac31492018-02-15 20:39:13 +0100337 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
338 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200339
340 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
341 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
342 BSSGP.receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
Harald Welte5ac31492018-02-15 20:39:13 +0100343 l3_mt := bd.l3_mt;
344 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200345 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
346
347 if (umts_aka_challenge and not force_gsm_sres) {
348 /* set UMTS response instead */
349 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
350 valueField := substr(g_pars.vec.res, 0, 4)
351 };
352 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
353 elementIdentifier := '21'O,
354 lengthIndicator := lengthof(g_pars.vec.res) - 4,
355 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
356 };
357 }
358
359 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100360 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
361 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
362 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
363 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
364 }
365 BSSGP.send(l3_mo);
Harald Welte76dee092018-02-16 22:12:59 +0100366 } else {
367 /* wait for identity procedure */
368 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100369 }
Harald Welte76dee092018-02-16 22:12:59 +0100370
Harald Welte5ac31492018-02-15 20:39:13 +0100371 deactivate(di);
372}
373
Harald Weltef70997d2018-02-17 10:11:19 +0100374function f_upd_ptmsi_and_tlli(OCT4 p_tmsi) runs on BSSGP_ConnHdlr {
375 g_pars.p_tmsi := p_tmsi;
376 /* update TLLI */
377 g_pars.tlli_old := g_pars.tlli;
378 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
379 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli);
380}
381
Harald Welte04683d02018-02-16 22:43:45 +0100382function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
383 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100384 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
385 if (not (g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc == aa_plmn)) {
386 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
387 & "; expected " & hex2str(g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc));
388 self.stop;
389 }
Harald Welte04683d02018-02-16 22:43:45 +0100390 g_pars.ra := aa.routingAreaIdentification;
391 if (ispresent(aa.allocatedPTMSI)) {
392 if (not g_pars.net.expect_ptmsi) {
393 setverdict(fail, "unexpected P-TMSI allocation");
394 self.stop;
395 }
Harald Weltef70997d2018-02-17 10:11:19 +0100396 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100397 }
398 if (ispresent(aa.msIdentity)) {
399 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
400 self.stop;
401 }
402 /* P-TMSI.sig */
403 if (ispresent(aa.ptmsiSignature)) {
404 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
405 }
406 /* updateTimer */
407 // aa.readyTimer
408 /* T3302, T3319, T3323, T3312_ext, T3324 */
409}
410
Harald Welte91636de2018-02-17 10:16:14 +0100411function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra) runs on BSSGP_ConnHdlr {
412 /* mandatory IE */
413 g_pars.ra := ra.routingAreaId;
414 if (ispresent(ra.allocatedPTMSI)) {
415 if (not g_pars.net.expect_ptmsi) {
416 setverdict(fail, "unexpected P-TMSI allocation");
417 self.stop;
418 }
419 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
420 }
421 if (ispresent(ra.msIdentity)) {
422 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
423 self.stop;
424 }
425 /* P-TMSI.sig */
426 if (ispresent(ra.ptmsiSignature)) {
427 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
428 }
429 /* updateTimer */
430 // aa.readyTimer
431 /* T3302, T3319, T3323, T3312_ext, T3324 */
432}
433
434
Harald Welte5a4fa042018-02-16 20:59:21 +0100435function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
436 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
437}
438
Harald Welte23178c52018-02-17 09:36:33 +0100439/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100440private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100441 if (ispresent(g_pars.p_tmsi)) {
442 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
443 } else {
444 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
445 }
446}
447
Harald Welte311ec272018-02-17 09:40:03 +0100448private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100449 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100450 /* Expect MSC to perform LU with HLR */
451 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100452 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
453 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
454 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100455 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
456 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
457}
458
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200459private function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100460 var BssgpDecoded bd;
Harald Welte5a4fa042018-02-16 20:59:21 +0100461 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200462 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 +0100463
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200464 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
465 * 3G auth vectors */
466 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
467 /* The thing is, if the solSACapability is 'omit', then the
468 * revisionLevelIndicatior is at the wrong place! */
469 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
470
471 BSSGP.send(attach_req);
472 f_gmm_auth(umts_aka_challenge, force_gsm_sres);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200473 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100474 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100475
Harald Welte04683d02018-02-16 22:43:45 +0100476 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
477 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
478 }
479 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welte5ac31492018-02-15 20:39:13 +0100480 BSSGP.send(ts_GMM_ATTACH_COMPL);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200481}
482
483private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
484 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100485 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100486}
487
488testcase TC_attach() runs on test_CT {
489 var BSSGP_ConnHdlr vc_conn;
490 f_init();
491 f_sleep(1.0);
492 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1);
493 vc_conn.done;
494}
495
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100496testcase TC_attach_mnc3() runs on test_CT {
497 var BSSGP_ConnHdlr vc_conn;
498 f_init('023042'H);
499 f_sleep(1.0);
500 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1001);
501 vc_conn.done;
502}
503
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200504private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
505 f_gmm_attach(true, false);
506 setverdict(pass);
507}
508testcase TC_attach_umts_aka_umts_res() runs on test_CT {
509 var BSSGP_ConnHdlr vc_conn;
510 f_init();
511 f_sleep(1.0);
512 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb[0], 1002);
513 vc_conn.done;
514}
515
516private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
517 f_gmm_attach(true, true);
518 setverdict(pass);
519}
520testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
521 var BSSGP_ConnHdlr vc_conn;
522 f_init();
523 f_sleep(1.0);
524 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb[0], 1003);
525 vc_conn.done;
526}
527
Harald Welte5b7c8122018-02-16 21:48:17 +0100528/* MS never responds to ID REQ, expect ATTACH REJECT */
529private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100530 var RoutingAreaIdentificationV old_ra := f_random_RAI();
531
Harald Welte23178c52018-02-17 09:36:33 +0100532 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100533 alt {
Harald Welte1967d472018-02-16 21:54:21 +0100534 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100535 /* don't send ID Response */
536 repeat;
537 }
Harald Welte1967d472018-02-16 21:54:21 +0100538 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100539 setverdict(pass);
540 }
Harald Welte1967d472018-02-16 21:54:21 +0100541 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100542 setverdict(fail, "Wrong Attach Reject Cause");
543 }
544 }
545}
546testcase TC_attach_auth_id_timeout() runs on test_CT {
547 var BSSGP_ConnHdlr vc_conn;
548 f_init();
549 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb[0], 2, 40.0);
550 vc_conn.done;
551}
552
553/* HLR never responds to SAI REQ, expect ATTACH REJECT */
554private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100555 var RoutingAreaIdentificationV old_ra := f_random_RAI();
556
Harald Welte23178c52018-02-17 09:36:33 +0100557 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100558 alt {
559 [] as_mm_identity();
560 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
561 }
562 /* don't send SAI-response from HLR */
Harald Welte1967d472018-02-16 21:54:21 +0100563 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100564 setverdict(pass);
565}
566testcase TC_attach_auth_sai_timeout() runs on test_CT {
567 var BSSGP_ConnHdlr vc_conn;
568 f_init();
569 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb[0], 3);
570 vc_conn.done;
571}
572
Harald Weltefe253882018-02-17 09:25:00 +0100573/* HLR rejects SAI, expect ATTACH REJECT */
574private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100575 var RoutingAreaIdentificationV old_ra := f_random_RAI();
576
Harald Welte23178c52018-02-17 09:36:33 +0100577 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100578 alt {
579 [] as_mm_identity();
580 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
581 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
582 }
583 }
584 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
585 setverdict(pass);
586}
587testcase TC_attach_auth_sai_reject() runs on test_CT {
588 var BSSGP_ConnHdlr vc_conn;
589 f_init();
Harald Welteb7c14e92018-02-17 09:29:16 +0100590 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb[0], 4);
Harald Weltefe253882018-02-17 09:25:00 +0100591 vc_conn.done;
592}
593
Harald Welte5b7c8122018-02-16 21:48:17 +0100594/* HLR never responds to UL REQ, expect ATTACH REJECT */
595private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100596 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100597 var RoutingAreaIdentificationV old_ra := f_random_RAI();
598
Harald Welte23178c52018-02-17 09:36:33 +0100599 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100600 f_gmm_auth();
601 /* Expect MSC to perform LU with HLR */
602 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
603 /* Never follow-up with ISD_REQ or UL_RES */
604 alt {
Harald Welte1967d472018-02-16 21:54:21 +0100605 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100606 setverdict(pass);
607 }
Harald Welte04683d02018-02-16 22:43:45 +0100608 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
609 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100610 setverdict(fail);
611 }
612 }
613}
614testcase TC_attach_gsup_lu_timeout() runs on test_CT {
615 var BSSGP_ConnHdlr vc_conn;
616 f_init();
617 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100618 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb[0], 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100619 vc_conn.done;
620}
621
Harald Welteb7c14e92018-02-17 09:29:16 +0100622/* HLR rejects UL REQ, expect ATTACH REJECT */
623private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
624 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100625 var RoutingAreaIdentificationV old_ra := f_random_RAI();
626
Harald Welte23178c52018-02-17 09:36:33 +0100627 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100628 f_gmm_auth();
629 /* Expect MSC to perform LU with HLR */
630 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
631 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
632 }
633 alt {
634 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
635 setverdict(pass);
636 }
637 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
638 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
639 setverdict(fail);
640 }
641 }
642}
643testcase TC_attach_gsup_lu_reject() runs on test_CT {
644 var BSSGP_ConnHdlr vc_conn;
645 f_init();
646 f_sleep(1.0);
647 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb[0], 6);
648 vc_conn.done;
649}
650
651
Harald Welte3823e2e2018-02-16 21:53:48 +0100652/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
653private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100654 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100655 var RoutingAreaIdentificationV old_ra := f_random_RAI();
656
Harald Welte23178c52018-02-17 09:36:33 +0100657 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100658 f_gmm_auth();
659 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100660 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100661
Harald Welte04683d02018-02-16 22:43:45 +0100662 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
663 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
664 }
Harald Welte3823e2e2018-02-16 21:53:48 +0100665 BSSGP.send(ts_GMM_ATTACH_COMPL);
666 setverdict(pass);
667}
Harald Welte3823e2e2018-02-16 21:53:48 +0100668testcase TC_attach_combined() runs on test_CT {
669 var BSSGP_ConnHdlr vc_conn;
670 f_init();
671 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100672 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb[0], 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100673 vc_conn.done;
674}
675
Harald Welte76dee092018-02-16 22:12:59 +0100676/* Attempt of GPRS ATTACH in 'accept all' mode */
677private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100678 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100679 var RoutingAreaIdentificationV old_ra := f_random_RAI();
680
681 g_pars.net.expect_auth := false;
682
Harald Welte23178c52018-02-17 09:36:33 +0100683 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100684 f_gmm_auth();
Harald Welte04683d02018-02-16 22:43:45 +0100685 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
686 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
687 }
Harald Welte76dee092018-02-16 22:12:59 +0100688 BSSGP.send(ts_GMM_ATTACH_COMPL);
689 setverdict(pass);
690}
691testcase TC_attach_accept_all() runs on test_CT {
692 var BSSGP_ConnHdlr vc_conn;
693 f_init();
694 f_sleep(1.0);
695 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Harald Welteb7c14e92018-02-17 09:29:16 +0100696 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 8);
Harald Welte76dee092018-02-16 22:12:59 +0100697 vc_conn.done;
698}
Harald Welte5b7c8122018-02-16 21:48:17 +0100699
Harald Welteb2124b22018-02-16 22:26:56 +0100700/* Attempt of GPRS ATTACH in 'accept all' mode */
701private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100702 var RoutingAreaIdentificationV old_ra := f_random_RAI();
703
704 /* Simulate a foreign IMSI */
705 g_pars.imsi := '001010123456789'H;
706 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
707
708 g_pars.net.expect_auth := false;
709
Harald Welte23178c52018-02-17 09:36:33 +0100710 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100711 alt {
712 [] as_mm_identity();
713 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
714 setverdict(pass);
715 }
716 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
717 setverdict(pass);
718 }
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200719 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
720 setverdict(fail);
721 }
Harald Welteb2124b22018-02-16 22:26:56 +0100722 }
723}
724testcase TC_attach_closed() runs on test_CT {
725 var BSSGP_ConnHdlr vc_conn;
726 f_init();
727 f_sleep(1.0);
728 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
729 /* test with foreign IMSI: Must Reject */
Harald Welteb7c14e92018-02-17 09:29:16 +0100730 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100731 vc_conn.done;
732 /* test with home IMSI: Must Accept */
Harald Welteb7c14e92018-02-17 09:29:16 +0100733 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100734 vc_conn.done;
735}
736
Harald Welte04683d02018-02-16 22:43:45 +0100737/* Routing Area Update from Unknown TLLI -> REJECT */
738private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100739 var RoutingAreaIdentificationV old_ra := f_random_RAI();
740
Harald Welte23178c52018-02-17 09:36:33 +0100741 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 +0100742 alt {
743 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
744 setverdict(pass);
745 }
746 /* FIXME: Expect XID RESET? */
747 [] BSSGP.receive { repeat; }
748 }
749}
750testcase TC_rau_unknown() runs on test_CT {
751 var BSSGP_ConnHdlr vc_conn;
752 f_init();
753 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100754 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb[0], 11);
Harald Welte04683d02018-02-16 22:43:45 +0100755 vc_conn.done;
756}
757
Harald Welte91636de2018-02-17 10:16:14 +0100758private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
759 var BssgpDecoded bd;
760
761 /* first perform regular attach */
762 f_TC_attach(id);
763
764 /* then send RAU */
765 BSSGP.send(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit));
766 alt {
767 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
768 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept);
Alexander Couzens80ec1ea2018-05-12 16:44:36 +0200769 BSSGP.send(ts_GMM_RAU_COMPL);
Harald Welte91636de2018-02-17 10:16:14 +0100770 setverdict(pass);
771 }
772 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
773 setverdict(fail, "Unexpected RAU Reject");
774 }
775 [] BSSGP.receive { repeat; }
776 }
777}
778testcase TC_attach_rau() runs on test_CT {
779 var BSSGP_ConnHdlr vc_conn;
780 f_init();
781 f_sleep(1.0);
782 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb[0], 12);
783 vc_conn.done;
784}
Harald Welte04683d02018-02-16 22:43:45 +0100785
Harald Welte6abb9fe2018-02-17 15:24:48 +0100786/* general GPRS DETACH helper */
787function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge) runs on BSSGP_ConnHdlr {
788 var BssgpDecoded bd;
789 timer T := 5.0;
790 BSSGP.send(ts_GMM_DET_REQ_MO(detach_type, power_off));
791 if (expect_purge) {
792 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
793 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
794 }
795 T.start;
796 alt {
797 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
798 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
799 }
800 [power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
801 g_pars.ra := omit;
802 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
803 /* TODO: check if any PDP contexts are deactivated on network side? */
804 }
805 [power_off] T.timeout {
806 setverdict(pass);
807 }
808 [not power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
809 g_pars.ra := omit;
810 setverdict(pass);
811 /* TODO: check if any PDP contexts are deactivated on network side? */
812 }
813 [] BSSGP.receive { repeat; }
814 }
815}
816
817/* IMSI DETACH (non-power-off) for unknown TLLI */
818private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
819 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
820}
821testcase TC_detach_unknown_nopoweroff() runs on test_CT {
822 var BSSGP_ConnHdlr vc_conn;
823 f_init();
824 f_sleep(1.0);
825 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb[0], 13);
826 vc_conn.done;
827}
828
829/* IMSI DETACH (power-off) for unknown TLLI */
830private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
831 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
832}
833testcase TC_detach_unknown_poweroff() runs on test_CT {
834 var BSSGP_ConnHdlr vc_conn;
835 f_init();
836 f_sleep(1.0);
837 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb[0], 14);
838 vc_conn.done;
839}
840
841/* IMSI DETACH (non-power-off) for known TLLI */
842private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
843 /* first perform regular attach */
844 f_TC_attach(id);
845
846 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
847}
848testcase TC_detach_nopoweroff() runs on test_CT {
849 var BSSGP_ConnHdlr vc_conn;
850 f_init();
851 f_sleep(1.0);
852 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb[0], 15);
853 vc_conn.done;
854}
855
856/* IMSI DETACH (power-off) for known TLLI */
857private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
858 /* first perform regular attach */
859 f_TC_attach(id);
860
861 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
862}
863testcase TC_detach_poweroff() 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_poweroff), testcasename(), g_gb[0], 16);
868 vc_conn.done;
869}
870
Harald Welteeded9ad2018-02-17 20:57:34 +0100871type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100872 BIT3 tid, /* L3 Transaction ID */
873 BIT4 nsapi, /* SNDCP NSAPI */
874 BIT4 sapi, /* LLC SAPI */
875 QoSV qos, /* QoS parameters */
876 PDPAddressV addr, /* IP address */
877 octetstring apn optional, /* APN name */
878 ProtocolConfigOptionsV pco optional, /* protoco config opts */
879 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100880 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100881 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100882
Harald Welte822f9102018-02-18 20:39:06 +0100883 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
884 OCT4 ggsn_tei_u, /* GGSN TEI User */
885 octetstring ggsn_ip_c, /* GGSN IP Control */
886 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200887 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100888
Harald Welte822f9102018-02-18 20:39:06 +0100889 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
890 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
891 octetstring sgsn_ip_c optional, /* SGSN IP Control */
892 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100893};
894
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100895
896private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
897 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
898 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
899 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
900 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
901 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
902 f_gtp_register_teid(apars.ggsn_tei_c);
903 f_gtp_register_teid(apars.ggsn_tei_u);
904}
905
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200906function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100907 var boolean exp_rej := ispresent(apars.exp_rej_cause);
908 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200909 var template Recovery_gtpc recovery := omit;
910
911 if (send_recovery) {
912 recovery := ts_Recovery(apars.ggsn_restart_ctr);
913 }
Harald Welteeded9ad2018-02-17 20:57:34 +0100914
915 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
916 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100917 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
918 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
919 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
920 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
921 apars.sgsn_tei_c, apars.gtp_resp_cause,
922 apars.ggsn_tei_c, apars.ggsn_tei_u,
923 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200924 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
925 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +0100926 }
927 alt {
Harald Welte28307082018-02-18 12:14:18 +0100928 [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 +0100929 setverdict(pass);
930 }
Harald Welte28307082018-02-18 12:14:18 +0100931 [exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100932 setverdict(fail, "Unexpected PDP CTX ACT ACC");
933 }
Harald Welte28307082018-02-18 12:14:18 +0100934 [not exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100935 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
936 }
Harald Welte28307082018-02-18 12:14:18 +0100937 [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 +0100938 setverdict(pass);
939 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100940 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +0100941 }
942}
943
Harald Welte6f203162018-02-18 22:04:55 +0100944function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
945 var boolean exp_rej := ispresent(apars.exp_rej_cause);
946 var Gtp1cUnitdata g_ud;
947
948 BSSGP.send(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
949 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
950 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
951 BSSGP.clear;
952 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
953 }
954 alt {
955 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
956 setverdict(pass);
957 }
958 [] as_xid(apars);
959 }
960}
961
Harald Welte57b9b7f2018-02-18 22:28:13 +0100962function f_pdp_ctx_deact_mt(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
963 var Gtp1cUnitdata g_ud;
964 var integer seq_nr := 23;
965 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
966
967 BSSGP.clear;
Pau Espin Pedrol84667222018-07-13 19:08:14 +0200968 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
Harald Welte57b9b7f2018-02-18 22:28:13 +0100969
970 interleave {
Pau Espin Pedrolbcddb8c2018-07-16 12:28:03 +0200971 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Harald Welte57b9b7f2018-02-18 22:28:13 +0100972 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
973 }
974 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) { }
975 }
976}
977
Harald Welte6f203162018-02-18 22:04:55 +0100978
Harald Welteeded9ad2018-02-17 20:57:34 +0100979/* Table 10.5.156/3GPP TS 24.008 */
980template (value) QoSV t_QosDefault := {
981 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
982 delayClass := '100'B, /* best effort */
983 spare1 := '00'B,
984 precedenceClass := '010'B, /* normal */
985 spare2 := '0'B,
986 peakThroughput := '0000'B, /* subscribed */
987 meanThroughput := '00000'B, /* subscribed */
988 spare3 := '000'B,
989 deliverErroneusSDU := omit,
990 deliveryOrder := omit,
991 trafficClass := omit,
992 maxSDUSize := omit,
993 maxBitrateUplink := omit,
994 maxBitrateDownlink := omit,
995 sduErrorRatio := omit,
996 residualBER := omit,
997 trafficHandlingPriority := omit,
998 transferDelay := omit,
999 guaranteedBitRateUplink := omit,
1000 guaranteedBitRateDownlink := omit,
1001 sourceStatisticsDescriptor := omit,
1002 signallingIndication := omit,
1003 spare4 := omit,
1004 maxBitrateDownlinkExt := omit,
1005 guaranteedBitRateDownlinkExt := omit,
1006 maxBitrateUplinkExt := omit,
1007 guaranteedBitRateUplinkExt := omit,
1008 maxBitrateDownlinkExt2 := omit,
1009 guaranteedBitRateDownlinkExt2 := omit,
1010 maxBitrateUplinkExt2 := omit,
1011 guaranteedBitRateUplinkExt2 := omit
1012}
1013
1014/* 10.5.6.4 / 3GPP TS 24.008 */
1015template (value) PDPAddressV t_AddrIPv4dyn := {
1016 pdpTypeOrg := '0001'B, /* IETF */
1017 spare := '0000'B,
1018 pdpTypeNum := '21'O, /* IPv4 */
1019 addressInfo := omit
1020}
1021template (value) PDPAddressV t_AddrIPv6dyn := {
1022 pdpTypeOrg := '0001'B, /* IETF */
1023 spare := '0000'B,
1024 pdpTypeNum := '53'O, /* IPv6 */
1025 addressInfo := omit
1026}
1027
Harald Welte37692d82018-02-18 15:21:34 +01001028template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001029 tid := '000'B,
1030 nsapi := '0101'B, /* < 5 are reserved */
1031 sapi := '0011'B, /* 3/5/9/11 */
1032 qos := t_QosDefault,
1033 addr := t_AddrIPv4dyn,
1034 apn := omit,
1035 pco := omit,
1036 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001037 gtp_resp_cause := int2oct(128, 1),
1038 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001039
1040 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001041 ggsn_tei_c := f_rnd_octstring(4),
1042 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001043 ggsn_ip_c := f_inet_addr(ggsn_ip),
1044 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001045 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001046
Harald Welteeded9ad2018-02-17 20:57:34 +01001047 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001048 sgsn_tei_u := omit,
1049 sgsn_ip_c := omit,
1050 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001051}
1052
Harald Welte37692d82018-02-18 15:21:34 +01001053template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1054 connId := 1,
1055 remName := f_inet_ntoa(ip),
1056 remPort := GTP1U_PORT
1057}
1058
1059template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1060 connId := 1,
1061 remName := f_inet_ntoa(ip),
1062 remPort := GTP1C_PORT
1063}
1064
1065private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1066 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1067 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1068}
1069
1070private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
1071 [] BSSGP.receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
1072 repeat;
1073 }
1074}
1075
1076template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1077 pDU_SN_UNITDATA := {
1078 nsapi := nsapi,
1079 moreBit := ?,
1080 snPduType := '1'B,
1081 firstSegmentIndicator := ?,
1082 spareBit := ?,
1083 pcomp := ?,
1084 dcomp := ?,
1085 npduNumber := ?,
1086 segmentNumber := ?,
1087 npduNumberContinued := ?,
1088 dataSegmentSnUnitdataPdu := payload
1089 }
1090}
1091
1092/* simple case: single segment, no compression */
1093template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1094 pDU_SN_UNITDATA := {
1095 nsapi := nsapi,
1096 moreBit := '0'B,
1097 snPduType := '1'B,
1098 firstSegmentIndicator := '1'B,
1099 spareBit := '0'B,
1100 pcomp := '0000'B,
1101 dcomp := '0000'B,
1102 npduNumber := '0000'B,
1103 segmentNumber := '0000'B,
1104 npduNumberContinued := '00'O,
1105 dataSegmentSnUnitdataPdu := payload
1106 }
1107}
1108
1109/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1110private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1111 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1112 f_gtpu_send(apars, payload);
1113 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1114 alt {
1115 [] as_xid(apars);
1116 [] BSSGP.receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1117 }
1118}
1119
1120private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1121 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1122 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1123 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
1124 BSSGP.send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
1125 f_gtpu_send(apars, payload);
1126 /* Expect PDU via GTP from SGSN on simulated GGSN */
1127 alt {
1128 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1129 }
1130}
1131
Harald Welteeded9ad2018-02-17 20:57:34 +01001132private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001133 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001134
1135 /* first perform regular attach */
1136 f_TC_attach(id);
1137
1138 f_pdp_ctx_act(apars);
1139}
1140testcase TC_attach_pdp_act() runs on test_CT {
1141 var BSSGP_ConnHdlr vc_conn;
1142 f_init();
1143 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1144 vc_conn.done;
1145}
Harald Welteb2124b22018-02-16 22:26:56 +01001146
Harald Welte835b15f2018-02-18 14:39:11 +01001147/* PDP Context activation for not-attached subscriber; expect fail */
1148private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001149 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welte835b15f2018-02-18 14:39:11 +01001150 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1151 apars.apn, apars.pco));
1152 alt {
1153 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
1154 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
1155 setverdict(pass);
1156 }
1157 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1158 setverdict(fail, "Unexpected GTP PDP CTX ACT");
1159 }
1160 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
1161 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
1162 }
1163 [] BSSGP.receive { repeat; }
1164 }
1165}
1166testcase TC_pdp_act_unattached() runs on test_CT {
1167 var BSSGP_ConnHdlr vc_conn;
1168 f_init();
1169 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1170 vc_conn.done;
1171}
1172
Harald Welte37692d82018-02-18 15:21:34 +01001173/* ATTACH + PDP CTX ACT + user plane traffic */
1174private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1175 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1176
1177 /* first perform regular attach */
1178 f_TC_attach(id);
1179 /* then activate PDP context */
1180 f_pdp_ctx_act(apars);
1181 /* then transceive a downlink PDU */
1182 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1183 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1184}
1185testcase TC_attach_pdp_act_user() runs on test_CT {
1186 var BSSGP_ConnHdlr vc_conn;
1187 f_init();
1188 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1189 vc_conn.done;
1190}
1191
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001192/* ATTACH + PDP CTX ACT; reject from GGSN */
1193private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1194 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1195
1196 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1197 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1198
1199 /* first perform regular attach */
1200 f_TC_attach(id);
1201 /* then activate PDP context */
1202 f_pdp_ctx_act(apars);
1203}
1204testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1205 var BSSGP_ConnHdlr vc_conn;
1206 f_init();
1207 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1208 vc_conn.done;
1209}
Harald Welte835b15f2018-02-18 14:39:11 +01001210
Harald Welte6f203162018-02-18 22:04:55 +01001211/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1212private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1213 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1214
1215 /* first perform regular attach */
1216 f_TC_attach(id);
1217 /* then activate PDP context */
1218 f_pdp_ctx_act(apars);
1219 /* then transceive a downlink PDU */
1220 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1221 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1222
1223 f_pdp_ctx_deact_mo(apars, '00'O);
1224}
1225testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1226 var BSSGP_ConnHdlr vc_conn;
1227 f_init();
1228 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1229 vc_conn.done;
1230}
1231
Harald Welte57b9b7f2018-02-18 22:28:13 +01001232/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1233private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1234 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1235
1236 /* first perform regular attach */
1237 f_TC_attach(id);
1238 /* then activate PDP context */
1239 f_pdp_ctx_act(apars);
1240 /* then transceive a downlink PDU */
1241 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1242 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1243
1244 f_pdp_ctx_deact_mt(apars, '00'O);
1245}
1246testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1247 var BSSGP_ConnHdlr vc_conn;
1248 f_init();
1249 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1250 vc_conn.done;
1251}
1252
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001253/* ATTACH + ATTACH (2nd) */
1254private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1255 g_pars.t_guard := 5.0;
1256
1257 /* first perform regular attach */
1258 f_TC_attach(id);
1259
1260 /* second to perform regular attach */
1261 f_TC_attach(id);
1262}
1263
1264
1265testcase TC_attach_second_attempt() runs on test_CT {
1266 var BSSGP_ConnHdlr vc_conn;
1267 f_init();
1268 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1269 vc_conn.done;
1270}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001271
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001272private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001273 var Gtp1cUnitdata g_ud;
1274 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1275
1276 /* first perform regular attach */
1277 f_TC_attach(id);
1278 /* Activate a pdp context against the GGSN */
1279 f_pdp_ctx_act(apars);
1280 /* Wait to receive first echo request and send initial Restart counter */
1281 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1282 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1283 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1284 }
1285 /* Wait to receive second echo request and send incremented Restart
1286 counter. This will fake a restarted GGSN, and pdp ctx allocated
1287 should be released by SGSN */
1288 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1289 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1290 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1291 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1292 }
1293 var OCT1 cause_network_failure := int2oct(38, 1)
1294 alt {
1295 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
1296 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1297 setverdict(pass);
1298 }
1299 [] as_xid(apars);
1300 }
1301 setverdict(pass);
1302}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001303/* ATTACH + trigger Recovery procedure through EchoResp */
1304testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001305 var BSSGP_ConnHdlr vc_conn;
1306 g_use_echo := true
1307 f_init();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001308 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 +02001309 vc_conn.done;
1310 g_use_echo := false
1311}
1312
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001313private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1314 var Gtp1cUnitdata g_ud;
1315 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1316 var integer seq_nr := 23;
1317 var GtpPeer peer;
1318 /* first perform regular attach */
1319 f_TC_attach(id);
1320
1321 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1322 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1323 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1324 f_pdp_ctx_act(apars, true);
1325
1326 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1327/* received. */
1328 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1329
1330 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1331 would be great to have an active pdp context here before triggering
1332 Recovery, and making sure the the DEACT request is sent by the SGSN.
1333 */
1334
1335 /* Activate a pdp context against the GGSN, send incremented Recovery
1336 IE. This should trigger the recovery path, but still this specific
1337 CTX activation should work. */
1338 apars.exp_rej_cause := omit; /* default value for tests */
1339 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1340 f_pdp_ctx_act(apars, true);
1341
1342 setverdict(pass);
1343}
1344/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1345testcase TC_attach_restart_ctr_create() runs on test_CT {
1346 var BSSGP_ConnHdlr vc_conn;
1347 f_init();
1348 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb[0], 24, 30.0);
1349 vc_conn.done;
1350}
1351
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001352/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1353private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1354 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1355 var integer seq_nr := 23;
1356 var GtpPeer peer;
1357 var integer i;
1358
1359 /* first perform regular attach */
1360 f_TC_attach(id);
1361 /* then activate PDP context */
1362 f_pdp_ctx_act(apars);
1363
1364 BSSGP.clear;
1365 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1366 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1367
1368 for (i := 0; i < 5; i := i+1) {
1369 alt {
1370 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
1371 [] as_xid(apars);
1372 }
1373 }
1374
1375 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1376
1377 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1378 setverdict(pass);
1379}
1380testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1381 var BSSGP_ConnHdlr vc_conn;
1382 f_init();
1383 f_sleep(1.0);
1384 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb[0], 25, 60.0);
1385 vc_conn.done;
1386}
1387
Alexander Couzens5e307b42018-05-22 18:12:20 +02001388private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1389 /* MS: perform regular attach */
1390 f_TC_attach(id);
1391
1392 /* HLR: cancel the location request */
1393 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1394 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001395
1396 /* ensure no Detach Request got received */
1397 timer T := 5.0;
1398 T.start;
1399 alt {
1400 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
1401 T.stop;
1402 setverdict(fail, "Unexpected GMM Detach Request");
1403 }
1404 [] T.timeout {
1405 setverdict(pass);
1406 self.stop;
1407 }
1408 [] BSSGP.receive {
1409 repeat;
1410 }
1411 }
1412}
1413
1414testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1415 /* MS <-> SGSN: GMM Attach
1416 * HLR -> SGSN: Cancel Location Request
1417 * HLR <- SGSN: Cancel Location Ack
1418 */
1419 var BSSGP_ConnHdlr vc_conn;
1420 f_init();
1421 f_sleep(1.0);
1422 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1423 vc_conn.done;
1424}
1425
1426
Alexander Couzensc87967a2018-05-22 16:09:54 +02001427private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1428 /* MS: perform regular attach */
1429 f_TC_attach(id);
1430
1431 /* HLR: cancel the location request */
1432 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1433 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1434 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1435
1436 /* MS: receive a Detach Request */
1437 BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1438 BSSGP.send(ts_GMM_DET_ACCEPT_MO);
1439
1440 setverdict(pass);
1441}
1442
1443testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1444 /* MS <-> SGSN: GMM Attach
1445 * HLR -> SGSN: Cancel Location Request
1446 * HLR <- SGSN: Cancel Location Ack
1447 * MS <- SGSN: Detach Request
1448 * SGSN-> MS: Detach Complete
1449 */
1450 var BSSGP_ConnHdlr vc_conn;
1451 f_init();
1452 f_sleep(1.0);
1453 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1454 vc_conn.done;
1455}
1456
1457
Alexander Couzens6c47f292018-05-22 17:09:49 +02001458private function f_hlr_location_cancel_request_unknown_subscriber(
1459 charstring id,
1460 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1461
1462 /* HLR: cancel the location request */
1463 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1464
1465 /* cause 2 = IMSI_UNKNOWN */
1466 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1467
1468 setverdict(pass);
1469}
1470
1471private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001472 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001473}
1474
1475testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1476 /* HLR -> SGSN: Cancel Location Request
1477 * HLR <- SGSN: Cancel Location Error
1478 */
1479
1480 var BSSGP_ConnHdlr vc_conn;
1481 f_init();
1482 f_sleep(1.0);
1483 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1484 vc_conn.done;
1485}
1486
1487private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001488 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001489}
1490
1491testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1492 /* HLR -> SGSN: Cancel Location Request
1493 * HLR <- SGSN: Cancel Location Error
1494 */
1495
1496 var BSSGP_ConnHdlr vc_conn;
1497 f_init();
1498 f_sleep(1.0);
1499 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1500 vc_conn.done;
1501}
1502
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001503private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1504 f_TC_attach(id);
1505 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1506}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001507
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001508testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1509 /* MS <-> SGSN: Attach
1510 * MS -> SGSN: Detach Req (Power off)
1511 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1512 */
1513 var BSSGP_ConnHdlr vc_conn;
1514 var integer id := 33;
1515 var charstring imsi := hex2str(f_gen_imsi(id));
1516
1517 f_init();
1518 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb[0], id);
1519 vc_conn.done;
1520
1521 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1522}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001523
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001524/* Attempt an attach, but loose the Identification Request (IMEI) */
1525private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1526 var integer count_req := 0;
1527 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1528
1529 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1530
1531 alt {
1532 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1533 /* break */
1534 }
1535 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1536 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1537 BSSGP.send(ts_GMM_ID_RESP(mi));
1538 repeat;
1539 }
1540 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1541 /* ignore ID REQ IMEI */
1542 count_req := count_req + 1;
1543 repeat;
1544 }
1545 }
1546 if (count_req != 5) {
1547 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
1548 }
1549 setverdict(pass);
1550}
1551
1552testcase TC_attach_no_imei_response() runs on test_CT {
1553 /* MS -> SGSN: Attach Request IMSI
1554 * MS <- SGSN: Identity Request IMSI (optional)
1555 * MS -> SGSN: Identity Response IMSI (optional)
1556 * MS <- SGSN: Identity Request IMEI
1557 * MS -x SGSN: no response
1558 * MS <- SGSN: re-send: Identity Request IMEI 4x
1559 * MS <- SGSN: Attach Reject
1560 */
1561 var BSSGP_ConnHdlr vc_conn;
1562 f_init();
1563 f_sleep(1.0);
1564 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1565 vc_conn.done;
1566}
1567
Alexander Couzens53f20562018-06-12 16:24:12 +02001568/* Attempt an attach, but loose the Identification Request (IMSI) */
1569private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1570 var integer count_req := 0;
1571 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1572
1573 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1574 g_pars.p_tmsi := 'c0000035'O;
1575
1576 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1577
1578 alt {
1579 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1580 /* break */
1581 }
1582 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1583 /* ignore ID REQ IMSI */
1584 count_req := count_req + 1;
1585 repeat;
1586 }
1587 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1588 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1589 BSSGP.send(ts_GMM_ID_RESP(mi));
1590 repeat;
1591 }
1592 }
1593 if (count_req != 5) {
1594 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
1595 }
1596 setverdict(pass);
1597}
1598
1599testcase TC_attach_no_imsi_response() runs on test_CT {
1600 /* MS -> SGSN: Attach Request TMSI (unknown)
1601 * MS <- SGSN: Identity Request IMEI (optional)
1602 * MS -> SGSN: Identity Response IMEI (optional)
1603 * MS <- SGSN: Identity Request IMSI
1604 * MS -x SGSN: no response
1605 * MS <- SGSN: re-send: Identity Request IMSI 4x
1606 * MS <- SGSN: Attach Reject
1607 */
1608 var BSSGP_ConnHdlr vc_conn;
1609 f_init();
1610 f_sleep(1.0);
1611 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1612 vc_conn.done;
1613}
1614
Alexander Couzenscf818962018-06-05 18:00:00 +02001615private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1616 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1617}
1618
1619testcase TC_attach_check_subscriber_list() runs on test_CT {
1620 /* MS <-> SGSN: Attach
1621 * VTY -> SGSN: Check if MS is in subscriber cache
1622 */
1623 var BSSGP_ConnHdlr vc_conn;
1624 var integer id := 34;
1625 var charstring imsi := hex2str(f_gen_imsi(id));
1626
1627 f_init();
1628 f_sleep(1.0);
1629 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], id);
1630 vc_conn.done;
1631
1632 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1633 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1634}
1635
Alexander Couzensf9858652018-06-07 16:14:53 +02001636private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1637 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1638 var BssgpDecoded bd;
1639
1640 /* unregister the old IMSI */
1641 f_bssgp_client_unregister(g_pars.imsi);
1642 /* Simulate a foreign IMSI */
1643 g_pars.imsi := '001010123456789'H;
1644 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
1645
1646 /* there is no auth */
1647 g_pars.net.expect_auth := false;
1648
1649 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
1650 f_gmm_auth();
1651 alt {
1652 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1653 setverdict(fail, "Received unexpected GMM Attach REJECT");
1654 }
1655 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
1656 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1657 BSSGP.send(ts_GMM_ATTACH_COMPL);
1658 setverdict(pass);
1659 }
1660 }
1661}
1662testcase TC_attach_closed_add_vty() runs on test_CT {
1663 /* VTY-> SGSN: policy close
1664 * MS -> SGSN: Attach Request
1665 * MS <- SGSN: Identity Request IMSI
1666 * MS -> SGSN: Identity Response IMSI
1667 * MS <- SGSN: Attach Reject
1668 * VTY-> SGSN: policy imsi-acl add IMSI
1669 * MS -> SGSN: Attach Request
1670 * MS <- SGSN: Identity Request IMSI
1671 * MS -> SGSN: Identity Response IMSI
1672 * MS <- SGSN: Identity Request IMEI
1673 * MS -> SGSN: Identity Response IMEI
1674 * MS <- SGSN: Attach Accept
1675 */
1676 var BSSGP_ConnHdlr vc_conn;
1677 f_init();
1678 f_sleep(1.0);
1679 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1680 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
1681 /* test with foreign IMSI: Must Reject */
1682 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
1683 vc_conn.done;
1684 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456789");
1685 /* test with same IMSI: Must Accept */
1686 vc_conn := f_start_handler(refers(f_TC_attach_closed_imsi_added), testcasename(), g_gb[0], 10);
1687 vc_conn.done;
1688}
1689
Alexander Couzens0085bd72018-06-12 19:08:44 +02001690/* Attempt an attach, but never answer a Attach Complete */
1691private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1692 var integer count_req := 0;
1693
1694 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1695 f_gmm_auth();
1696
1697 alt {
1698 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1699 /* break */
1700 }
1701 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
1702 /* ignore */
1703 count_req := count_req + 1;
1704 repeat;
1705 }
1706 }
1707 if (count_req != 5) {
1708 setverdict(fail, "Did not received GMM Attach Complete.");
1709 }
1710 setverdict(pass);
1711}
1712
1713testcase TC_attach_check_complete_resend() runs on test_CT {
1714 /* MS -> SGSN: Attach Request IMSI
1715 * MS <- SGSN: Identity Request *
1716 * MS -> SGSN: Identity Response *
1717 * MS <- SGSN: Attach Complete 5x
1718 */
1719 var BSSGP_ConnHdlr vc_conn;
1720 f_init();
1721 f_sleep(1.0);
1722 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb[0], 36, 60.0);
1723 vc_conn.done;
1724}
1725
Harald Welte5ac31492018-02-15 20:39:13 +01001726control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001727 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001728 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001729 execute( TC_attach_umts_aka_umts_res() );
1730 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001731 execute( TC_attach_auth_id_timeout() );
1732 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001733 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001734 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001735 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001736 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001737 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001738 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001739 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001740 execute( TC_attach_no_imsi_response() );
Alexander Couzensf9858652018-06-07 16:14:53 +02001741 execute( TC_attach_closed_add_vty(), 10.0 );
Alexander Couzenscf818962018-06-05 18:00:00 +02001742 execute( TC_attach_check_subscriber_list(), 10.0 );
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001743 execute( TC_attach_detach_check_subscriber_list(), 10.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02001744 execute( TC_attach_check_complete_resend() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001745 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001746 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1747 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1748 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001749 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001750 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001751 execute( TC_detach_unknown_nopoweroff() );
1752 execute( TC_detach_unknown_poweroff() );
1753 execute( TC_detach_nopoweroff() );
1754 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001755 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001756 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001757 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001758 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001759 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001760 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001761 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001762 execute( TC_attach_restart_ctr_echo() );
1763 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001764 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Harald Welte5ac31492018-02-15 20:39:13 +01001765}
Harald Welte96a33b02018-02-04 10:36:22 +01001766
1767
1768
1769}