blob: 78086af69329bf4585c9aa411c347b35c21093c8 [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
Pau Espin Pedrol482dde62018-07-18 13:47:42 +0200962function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +0100963 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 Pedrol482dde62018-07-18 13:47:42 +0200968 if (error_ind) {
969 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
970 } else {
971 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
972 }
973 alt {
Pau Espin Pedrolbcddb8c2018-07-16 12:28:03 +0200974 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Harald Welte57b9b7f2018-02-18 22:28:13 +0100975 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
976 }
Pau Espin Pedrol482dde62018-07-18 13:47:42 +0200977 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) { }
Harald Welte57b9b7f2018-02-18 22:28:13 +0100978 }
979}
980
Harald Welte6f203162018-02-18 22:04:55 +0100981
Harald Welteeded9ad2018-02-17 20:57:34 +0100982/* Table 10.5.156/3GPP TS 24.008 */
983template (value) QoSV t_QosDefault := {
984 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
985 delayClass := '100'B, /* best effort */
986 spare1 := '00'B,
987 precedenceClass := '010'B, /* normal */
988 spare2 := '0'B,
989 peakThroughput := '0000'B, /* subscribed */
990 meanThroughput := '00000'B, /* subscribed */
991 spare3 := '000'B,
992 deliverErroneusSDU := omit,
993 deliveryOrder := omit,
994 trafficClass := omit,
995 maxSDUSize := omit,
996 maxBitrateUplink := omit,
997 maxBitrateDownlink := omit,
998 sduErrorRatio := omit,
999 residualBER := omit,
1000 trafficHandlingPriority := omit,
1001 transferDelay := omit,
1002 guaranteedBitRateUplink := omit,
1003 guaranteedBitRateDownlink := omit,
1004 sourceStatisticsDescriptor := omit,
1005 signallingIndication := omit,
1006 spare4 := omit,
1007 maxBitrateDownlinkExt := omit,
1008 guaranteedBitRateDownlinkExt := omit,
1009 maxBitrateUplinkExt := omit,
1010 guaranteedBitRateUplinkExt := omit,
1011 maxBitrateDownlinkExt2 := omit,
1012 guaranteedBitRateDownlinkExt2 := omit,
1013 maxBitrateUplinkExt2 := omit,
1014 guaranteedBitRateUplinkExt2 := omit
1015}
1016
1017/* 10.5.6.4 / 3GPP TS 24.008 */
1018template (value) PDPAddressV t_AddrIPv4dyn := {
1019 pdpTypeOrg := '0001'B, /* IETF */
1020 spare := '0000'B,
1021 pdpTypeNum := '21'O, /* IPv4 */
1022 addressInfo := omit
1023}
1024template (value) PDPAddressV t_AddrIPv6dyn := {
1025 pdpTypeOrg := '0001'B, /* IETF */
1026 spare := '0000'B,
1027 pdpTypeNum := '53'O, /* IPv6 */
1028 addressInfo := omit
1029}
1030
Harald Welte37692d82018-02-18 15:21:34 +01001031template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001032 tid := '000'B,
1033 nsapi := '0101'B, /* < 5 are reserved */
1034 sapi := '0011'B, /* 3/5/9/11 */
1035 qos := t_QosDefault,
1036 addr := t_AddrIPv4dyn,
1037 apn := omit,
1038 pco := omit,
1039 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001040 gtp_resp_cause := int2oct(128, 1),
1041 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001042
1043 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001044 ggsn_tei_c := f_rnd_octstring(4),
1045 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001046 ggsn_ip_c := f_inet_addr(ggsn_ip),
1047 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001048 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001049
Harald Welteeded9ad2018-02-17 20:57:34 +01001050 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001051 sgsn_tei_u := omit,
1052 sgsn_ip_c := omit,
1053 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001054}
1055
Harald Welte37692d82018-02-18 15:21:34 +01001056template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1057 connId := 1,
1058 remName := f_inet_ntoa(ip),
1059 remPort := GTP1U_PORT
1060}
1061
1062template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1063 connId := 1,
1064 remName := f_inet_ntoa(ip),
1065 remPort := GTP1C_PORT
1066}
1067
1068private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1069 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1070 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1071}
1072
1073private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
1074 [] BSSGP.receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
1075 repeat;
1076 }
1077}
1078
1079template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1080 pDU_SN_UNITDATA := {
1081 nsapi := nsapi,
1082 moreBit := ?,
1083 snPduType := '1'B,
1084 firstSegmentIndicator := ?,
1085 spareBit := ?,
1086 pcomp := ?,
1087 dcomp := ?,
1088 npduNumber := ?,
1089 segmentNumber := ?,
1090 npduNumberContinued := ?,
1091 dataSegmentSnUnitdataPdu := payload
1092 }
1093}
1094
1095/* simple case: single segment, no compression */
1096template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1097 pDU_SN_UNITDATA := {
1098 nsapi := nsapi,
1099 moreBit := '0'B,
1100 snPduType := '1'B,
1101 firstSegmentIndicator := '1'B,
1102 spareBit := '0'B,
1103 pcomp := '0000'B,
1104 dcomp := '0000'B,
1105 npduNumber := '0000'B,
1106 segmentNumber := '0000'B,
1107 npduNumberContinued := '00'O,
1108 dataSegmentSnUnitdataPdu := payload
1109 }
1110}
1111
1112/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1113private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1114 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1115 f_gtpu_send(apars, payload);
1116 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1117 alt {
1118 [] as_xid(apars);
1119 [] BSSGP.receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1120 }
1121}
1122
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001123/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001124private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1125 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1126 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1127 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
1128 BSSGP.send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001129 /* Expect PDU via GTP from SGSN on simulated GGSN */
1130 alt {
1131 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1132 }
1133}
1134
Harald Welteeded9ad2018-02-17 20:57:34 +01001135private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001136 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001137
1138 /* first perform regular attach */
1139 f_TC_attach(id);
1140
1141 f_pdp_ctx_act(apars);
1142}
1143testcase TC_attach_pdp_act() runs on test_CT {
1144 var BSSGP_ConnHdlr vc_conn;
1145 f_init();
1146 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1147 vc_conn.done;
1148}
Harald Welteb2124b22018-02-16 22:26:56 +01001149
Harald Welte835b15f2018-02-18 14:39:11 +01001150/* PDP Context activation for not-attached subscriber; expect fail */
1151private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001152 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welte835b15f2018-02-18 14:39:11 +01001153 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1154 apars.apn, apars.pco));
1155 alt {
1156 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
1157 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
1158 setverdict(pass);
1159 }
1160 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1161 setverdict(fail, "Unexpected GTP PDP CTX ACT");
1162 }
1163 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
1164 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
1165 }
1166 [] BSSGP.receive { repeat; }
1167 }
1168}
1169testcase TC_pdp_act_unattached() runs on test_CT {
1170 var BSSGP_ConnHdlr vc_conn;
1171 f_init();
1172 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1173 vc_conn.done;
1174}
1175
Harald Welte37692d82018-02-18 15:21:34 +01001176/* ATTACH + PDP CTX ACT + user plane traffic */
1177private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1178 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1179
1180 /* first perform regular attach */
1181 f_TC_attach(id);
1182 /* then activate PDP context */
1183 f_pdp_ctx_act(apars);
1184 /* then transceive a downlink PDU */
1185 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1186 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1187}
1188testcase TC_attach_pdp_act_user() runs on test_CT {
1189 var BSSGP_ConnHdlr vc_conn;
1190 f_init();
1191 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1192 vc_conn.done;
1193}
1194
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001195/* ATTACH + PDP CTX ACT; reject from GGSN */
1196private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1197 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1198
1199 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1200 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1201
1202 /* first perform regular attach */
1203 f_TC_attach(id);
1204 /* then activate PDP context */
1205 f_pdp_ctx_act(apars);
1206}
1207testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1208 var BSSGP_ConnHdlr vc_conn;
1209 f_init();
1210 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1211 vc_conn.done;
1212}
Harald Welte835b15f2018-02-18 14:39:11 +01001213
Harald Welte6f203162018-02-18 22:04:55 +01001214/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1215private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1216 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1217
1218 /* first perform regular attach */
1219 f_TC_attach(id);
1220 /* then activate PDP context */
1221 f_pdp_ctx_act(apars);
1222 /* then transceive a downlink PDU */
1223 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1224 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1225
1226 f_pdp_ctx_deact_mo(apars, '00'O);
1227}
1228testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1229 var BSSGP_ConnHdlr vc_conn;
1230 f_init();
1231 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1232 vc_conn.done;
1233}
1234
Harald Welte57b9b7f2018-02-18 22:28:13 +01001235/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1236private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1237 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1238
1239 /* first perform regular attach */
1240 f_TC_attach(id);
1241 /* then activate PDP context */
1242 f_pdp_ctx_act(apars);
1243 /* then transceive a downlink PDU */
1244 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1245 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1246
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001247 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001248}
1249testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1250 var BSSGP_ConnHdlr vc_conn;
1251 f_init();
1252 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1253 vc_conn.done;
1254}
1255
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001256/* ATTACH + ATTACH (2nd) */
1257private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1258 g_pars.t_guard := 5.0;
1259
1260 /* first perform regular attach */
1261 f_TC_attach(id);
1262
1263 /* second to perform regular attach */
1264 f_TC_attach(id);
1265}
1266
1267
1268testcase TC_attach_second_attempt() runs on test_CT {
1269 var BSSGP_ConnHdlr vc_conn;
1270 f_init();
1271 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1272 vc_conn.done;
1273}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001274
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001275private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001276 var Gtp1cUnitdata g_ud;
1277 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1278
1279 /* first perform regular attach */
1280 f_TC_attach(id);
1281 /* Activate a pdp context against the GGSN */
1282 f_pdp_ctx_act(apars);
1283 /* Wait to receive first echo request and send initial Restart counter */
1284 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1285 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1286 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1287 }
1288 /* Wait to receive second echo request and send incremented Restart
1289 counter. This will fake a restarted GGSN, and pdp ctx allocated
1290 should be released by SGSN */
1291 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1292 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1293 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1294 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1295 }
1296 var OCT1 cause_network_failure := int2oct(38, 1)
1297 alt {
1298 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
1299 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1300 setverdict(pass);
1301 }
1302 [] as_xid(apars);
1303 }
1304 setverdict(pass);
1305}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001306/* ATTACH + trigger Recovery procedure through EchoResp */
1307testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001308 var BSSGP_ConnHdlr vc_conn;
1309 g_use_echo := true
1310 f_init();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001311 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 +02001312 vc_conn.done;
1313 g_use_echo := false
1314}
1315
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001316private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1317 var Gtp1cUnitdata g_ud;
1318 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1319 var integer seq_nr := 23;
1320 var GtpPeer peer;
1321 /* first perform regular attach */
1322 f_TC_attach(id);
1323
1324 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1325 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1326 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1327 f_pdp_ctx_act(apars, true);
1328
1329 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1330/* received. */
1331 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1332
1333 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1334 would be great to have an active pdp context here before triggering
1335 Recovery, and making sure the the DEACT request is sent by the SGSN.
1336 */
1337
1338 /* Activate a pdp context against the GGSN, send incremented Recovery
1339 IE. This should trigger the recovery path, but still this specific
1340 CTX activation should work. */
1341 apars.exp_rej_cause := omit; /* default value for tests */
1342 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1343 f_pdp_ctx_act(apars, true);
1344
1345 setverdict(pass);
1346}
1347/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1348testcase TC_attach_restart_ctr_create() runs on test_CT {
1349 var BSSGP_ConnHdlr vc_conn;
1350 f_init();
1351 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb[0], 24, 30.0);
1352 vc_conn.done;
1353}
1354
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001355/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1356private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1357 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1358 var integer seq_nr := 23;
1359 var GtpPeer peer;
1360 var integer i;
1361
1362 /* first perform regular attach */
1363 f_TC_attach(id);
1364 /* then activate PDP context */
1365 f_pdp_ctx_act(apars);
1366
1367 BSSGP.clear;
1368 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1369 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1370
1371 for (i := 0; i < 5; i := i+1) {
1372 alt {
1373 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
1374 [] as_xid(apars);
1375 }
1376 }
1377
1378 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1379
1380 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1381 setverdict(pass);
1382}
1383testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1384 var BSSGP_ConnHdlr vc_conn;
1385 f_init();
1386 f_sleep(1.0);
1387 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb[0], 25, 60.0);
1388 vc_conn.done;
1389}
1390
Alexander Couzens5e307b42018-05-22 18:12:20 +02001391private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1392 /* MS: perform regular attach */
1393 f_TC_attach(id);
1394
1395 /* HLR: cancel the location request */
1396 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1397 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001398
1399 /* ensure no Detach Request got received */
1400 timer T := 5.0;
1401 T.start;
1402 alt {
1403 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
1404 T.stop;
1405 setverdict(fail, "Unexpected GMM Detach Request");
1406 }
1407 [] T.timeout {
1408 setverdict(pass);
1409 self.stop;
1410 }
1411 [] BSSGP.receive {
1412 repeat;
1413 }
1414 }
1415}
1416
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001417/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1418private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1419 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1420
1421 /* first perform regular attach */
1422 f_TC_attach(id);
1423 /* then activate PDP context */
1424 f_pdp_ctx_act(apars);
1425 /* then transceive a downlink PDU */
1426 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1427
1428 /* Send Error indication as response from upload PDU and expect deact towards MS */
1429 f_pdp_ctx_deact_mt(apars, true);
1430}
1431testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1432 var BSSGP_ConnHdlr vc_conn;
1433 f_init();
1434 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb[0], 26);
1435 vc_conn.done;
1436}
1437
Alexander Couzens5e307b42018-05-22 18:12:20 +02001438testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1439 /* MS <-> SGSN: GMM Attach
1440 * HLR -> SGSN: Cancel Location Request
1441 * HLR <- SGSN: Cancel Location Ack
1442 */
1443 var BSSGP_ConnHdlr vc_conn;
1444 f_init();
1445 f_sleep(1.0);
1446 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1447 vc_conn.done;
1448}
1449
1450
Alexander Couzensc87967a2018-05-22 16:09:54 +02001451private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1452 /* MS: perform regular attach */
1453 f_TC_attach(id);
1454
1455 /* HLR: cancel the location request */
1456 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1457 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1458 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1459
1460 /* MS: receive a Detach Request */
1461 BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1462 BSSGP.send(ts_GMM_DET_ACCEPT_MO);
1463
1464 setverdict(pass);
1465}
1466
1467testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1468 /* MS <-> SGSN: GMM Attach
1469 * HLR -> SGSN: Cancel Location Request
1470 * HLR <- SGSN: Cancel Location Ack
1471 * MS <- SGSN: Detach Request
1472 * SGSN-> MS: Detach Complete
1473 */
1474 var BSSGP_ConnHdlr vc_conn;
1475 f_init();
1476 f_sleep(1.0);
1477 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1478 vc_conn.done;
1479}
1480
1481
Alexander Couzens6c47f292018-05-22 17:09:49 +02001482private function f_hlr_location_cancel_request_unknown_subscriber(
1483 charstring id,
1484 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1485
1486 /* HLR: cancel the location request */
1487 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1488
1489 /* cause 2 = IMSI_UNKNOWN */
1490 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1491
1492 setverdict(pass);
1493}
1494
1495private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001496 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001497}
1498
1499testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1500 /* HLR -> SGSN: Cancel Location Request
1501 * HLR <- SGSN: Cancel Location Error
1502 */
1503
1504 var BSSGP_ConnHdlr vc_conn;
1505 f_init();
1506 f_sleep(1.0);
1507 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1508 vc_conn.done;
1509}
1510
1511private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001512 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001513}
1514
1515testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1516 /* HLR -> SGSN: Cancel Location Request
1517 * HLR <- SGSN: Cancel Location Error
1518 */
1519
1520 var BSSGP_ConnHdlr vc_conn;
1521 f_init();
1522 f_sleep(1.0);
1523 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1524 vc_conn.done;
1525}
1526
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001527private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1528 f_TC_attach(id);
1529 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1530}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001531
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001532testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1533 /* MS <-> SGSN: Attach
1534 * MS -> SGSN: Detach Req (Power off)
1535 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1536 */
1537 var BSSGP_ConnHdlr vc_conn;
1538 var integer id := 33;
1539 var charstring imsi := hex2str(f_gen_imsi(id));
1540
1541 f_init();
1542 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb[0], id);
1543 vc_conn.done;
1544
1545 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1546}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001547
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001548/* Attempt an attach, but loose the Identification Request (IMEI) */
1549private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1550 var integer count_req := 0;
1551 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1552
1553 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1554
1555 alt {
1556 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1557 /* break */
1558 }
1559 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1560 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1561 BSSGP.send(ts_GMM_ID_RESP(mi));
1562 repeat;
1563 }
1564 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1565 /* ignore ID REQ IMEI */
1566 count_req := count_req + 1;
1567 repeat;
1568 }
1569 }
1570 if (count_req != 5) {
1571 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
1572 }
1573 setverdict(pass);
1574}
1575
1576testcase TC_attach_no_imei_response() runs on test_CT {
1577 /* MS -> SGSN: Attach Request IMSI
1578 * MS <- SGSN: Identity Request IMSI (optional)
1579 * MS -> SGSN: Identity Response IMSI (optional)
1580 * MS <- SGSN: Identity Request IMEI
1581 * MS -x SGSN: no response
1582 * MS <- SGSN: re-send: Identity Request IMEI 4x
1583 * MS <- SGSN: Attach Reject
1584 */
1585 var BSSGP_ConnHdlr vc_conn;
1586 f_init();
1587 f_sleep(1.0);
1588 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1589 vc_conn.done;
1590}
1591
Alexander Couzens53f20562018-06-12 16:24:12 +02001592/* Attempt an attach, but loose the Identification Request (IMSI) */
1593private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1594 var integer count_req := 0;
1595 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1596
1597 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1598 g_pars.p_tmsi := 'c0000035'O;
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 /* ignore ID REQ IMSI */
1608 count_req := count_req + 1;
1609 repeat;
1610 }
1611 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1612 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1613 BSSGP.send(ts_GMM_ID_RESP(mi));
1614 repeat;
1615 }
1616 }
1617 if (count_req != 5) {
1618 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
1619 }
1620 setverdict(pass);
1621}
1622
1623testcase TC_attach_no_imsi_response() runs on test_CT {
1624 /* MS -> SGSN: Attach Request TMSI (unknown)
1625 * MS <- SGSN: Identity Request IMEI (optional)
1626 * MS -> SGSN: Identity Response IMEI (optional)
1627 * MS <- SGSN: Identity Request IMSI
1628 * MS -x SGSN: no response
1629 * MS <- SGSN: re-send: Identity Request IMSI 4x
1630 * MS <- SGSN: Attach Reject
1631 */
1632 var BSSGP_ConnHdlr vc_conn;
1633 f_init();
1634 f_sleep(1.0);
1635 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1636 vc_conn.done;
1637}
1638
Alexander Couzenscf818962018-06-05 18:00:00 +02001639private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1640 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1641}
1642
1643testcase TC_attach_check_subscriber_list() runs on test_CT {
1644 /* MS <-> SGSN: Attach
1645 * VTY -> SGSN: Check if MS is in subscriber cache
1646 */
1647 var BSSGP_ConnHdlr vc_conn;
1648 var integer id := 34;
1649 var charstring imsi := hex2str(f_gen_imsi(id));
1650
1651 f_init();
1652 f_sleep(1.0);
1653 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], id);
1654 vc_conn.done;
1655
1656 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1657 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1658}
1659
Alexander Couzensf9858652018-06-07 16:14:53 +02001660private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1661 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1662 var BssgpDecoded bd;
1663
1664 /* unregister the old IMSI */
1665 f_bssgp_client_unregister(g_pars.imsi);
1666 /* Simulate a foreign IMSI */
1667 g_pars.imsi := '001010123456789'H;
1668 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
1669
1670 /* there is no auth */
1671 g_pars.net.expect_auth := false;
1672
1673 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
1674 f_gmm_auth();
1675 alt {
1676 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1677 setverdict(fail, "Received unexpected GMM Attach REJECT");
1678 }
1679 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
1680 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1681 BSSGP.send(ts_GMM_ATTACH_COMPL);
1682 setverdict(pass);
1683 }
1684 }
1685}
1686testcase TC_attach_closed_add_vty() runs on test_CT {
1687 /* VTY-> SGSN: policy close
1688 * MS -> SGSN: Attach Request
1689 * MS <- SGSN: Identity Request IMSI
1690 * MS -> SGSN: Identity Response IMSI
1691 * MS <- SGSN: Attach Reject
1692 * VTY-> SGSN: policy imsi-acl add IMSI
1693 * MS -> SGSN: Attach Request
1694 * MS <- SGSN: Identity Request IMSI
1695 * MS -> SGSN: Identity Response IMSI
1696 * MS <- SGSN: Identity Request IMEI
1697 * MS -> SGSN: Identity Response IMEI
1698 * MS <- SGSN: Attach Accept
1699 */
1700 var BSSGP_ConnHdlr vc_conn;
1701 f_init();
1702 f_sleep(1.0);
1703 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1704 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
1705 /* test with foreign IMSI: Must Reject */
1706 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
1707 vc_conn.done;
1708 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456789");
1709 /* test with same IMSI: Must Accept */
1710 vc_conn := f_start_handler(refers(f_TC_attach_closed_imsi_added), testcasename(), g_gb[0], 10);
1711 vc_conn.done;
1712}
1713
Alexander Couzens0085bd72018-06-12 19:08:44 +02001714/* Attempt an attach, but never answer a Attach Complete */
1715private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1716 var integer count_req := 0;
1717
1718 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1719 f_gmm_auth();
1720
1721 alt {
1722 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1723 /* break */
1724 }
1725 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
1726 /* ignore */
1727 count_req := count_req + 1;
1728 repeat;
1729 }
1730 }
1731 if (count_req != 5) {
1732 setverdict(fail, "Did not received GMM Attach Complete.");
1733 }
1734 setverdict(pass);
1735}
1736
1737testcase TC_attach_check_complete_resend() runs on test_CT {
1738 /* MS -> SGSN: Attach Request IMSI
1739 * MS <- SGSN: Identity Request *
1740 * MS -> SGSN: Identity Response *
1741 * MS <- SGSN: Attach Complete 5x
1742 */
1743 var BSSGP_ConnHdlr vc_conn;
1744 f_init();
1745 f_sleep(1.0);
1746 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb[0], 36, 60.0);
1747 vc_conn.done;
1748}
1749
Harald Welte5ac31492018-02-15 20:39:13 +01001750control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001751 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001752 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001753 execute( TC_attach_umts_aka_umts_res() );
1754 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001755 execute( TC_attach_auth_id_timeout() );
1756 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001757 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001758 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001759 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001760 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001761 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001762 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001763 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001764 execute( TC_attach_no_imsi_response() );
Alexander Couzensf9858652018-06-07 16:14:53 +02001765 execute( TC_attach_closed_add_vty(), 10.0 );
Alexander Couzenscf818962018-06-05 18:00:00 +02001766 execute( TC_attach_check_subscriber_list(), 10.0 );
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001767 execute( TC_attach_detach_check_subscriber_list(), 10.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02001768 execute( TC_attach_check_complete_resend() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001769 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001770 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1771 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1772 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001773 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001774 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001775 execute( TC_detach_unknown_nopoweroff() );
1776 execute( TC_detach_unknown_poweroff() );
1777 execute( TC_detach_nopoweroff() );
1778 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001779 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001780 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001781 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001782 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001783 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001784 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001785 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001786 execute( TC_attach_restart_ctr_echo() );
1787 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001788 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001789 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Harald Welte5ac31492018-02-15 20:39:13 +01001790}
Harald Welte96a33b02018-02-04 10:36:22 +01001791
1792
1793
1794}