blob: 0a20dd6997852e0957b3391f610e53135bb84ce7 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
3import from General_Types all;
4import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +01005import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +01006import from NS_Types all;
7import from NS_Emulation all;
8import from BSSGP_Types all;
9import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010010import from Osmocom_Gb_Types all;
11
12import from MobileL3_CommonIE_Types all;
13import from MobileL3_GMM_SM_Types all;
14import from MobileL3_Types all;
15import from L3_Templates all;
16import from L3_Common all;
17
18import from GSUP_Emulation all;
19import from GSUP_Types all;
20import from IPA_Emulation all;
21
Harald Welteeded9ad2018-02-17 20:57:34 +010022import from GTP_Emulation all;
23import from GTP_Templates all;
24import from GTP_CodecPort all;
25import from GTPC_Types all;
26import from GTPU_Types all;
27
Harald Weltea2526a82018-02-18 19:03:36 +010028import from LLC_Types all;
29import from LLC_Templates all;
30
31import from SNDCP_Types all;
32
Harald Weltebd194722018-02-16 22:11:08 +010033import from TELNETasp_PortType all;
34import from Osmocom_VTY_Functions all;
35
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010036import from GSM_RR_Types all;
37
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020038import from MobileL3_MM_Types all;
39
Harald Welteeded9ad2018-02-17 20:57:34 +010040
Harald Welte5ac31492018-02-15 20:39:13 +010041modulepar {
42 /* IP/port on which we run our internal GSUP/HLR emulation */
43 charstring mp_hlr_ip := "127.0.0.1";
44 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010045 charstring mp_ggsn_ip := "127.0.0.2";
Harald Welte5ac31492018-02-15 20:39:13 +010046};
47
48type record GbInstance {
49 NS_CT vc_NS,
50 BSSGP_CT vc_BSSGP,
51 BssgpConfig cfg
52};
Harald Welte96a33b02018-02-04 10:36:22 +010053
54type component test_CT {
Harald Welte5ac31492018-02-15 20:39:13 +010055 var GbInstance g_gb[3];
Harald Welte96a33b02018-02-04 10:36:22 +010056
Harald Welte5ac31492018-02-15 20:39:13 +010057 var GSUP_Emulation_CT vc_GSUP;
58 var IPA_Emulation_CT vc_GSUP_IPA;
59 /* only to get events from IPA underneath GSUP */
60 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010061
Harald Welteeded9ad2018-02-17 20:57:34 +010062 var GTP_Emulation_CT vc_GTP;
63
Harald Weltebd194722018-02-16 22:11:08 +010064 port TELNETasp_PT SGSNVTY;
65
Harald Welte96a33b02018-02-04 10:36:22 +010066 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +020067 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +010068};
69
Harald Welteeded9ad2018-02-17 20:57:34 +010070type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +010071 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +010072 timer g_Tguard;
Harald Welte5ac31492018-02-15 20:39:13 +010073}
74
75type record SGSN_ConnHdlrNetworkPars {
76 boolean expect_ptmsi,
77 boolean expect_auth,
78 boolean expect_ciph
79};
80
81type record BSSGP_ConnHdlrPars {
82 /* IMEI of the simulated ME */
83 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +020084 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +010085 hexstring imsi,
86 /* MSISDN of the simulated MS (probably unused) */
87 hexstring msisdn,
88 /* P-TMSI allocated to the simulated MS */
89 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +010090 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +010091 /* TLLI of the simulated MS */
92 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +010093 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +010094 RoutingAreaIdentificationV ra optional,
95 BssgpCellId bssgp_cell_id,
96 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +010097 SGSN_ConnHdlrNetworkPars net,
98 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +010099};
100
Harald Welte3fdbe822018-02-18 19:10:18 +0100101private function f_init_gb(inout GbInstance gb, charstring id) runs on test_CT {
102 gb.vc_NS := NS_CT.create(id & "-NS");
103 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP");
Harald Welte5ac31492018-02-15 20:39:13 +0100104 /* connect lower end of BSSGP emulation with NS upper port */
105 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
106 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
107 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
108
109 gb.vc_NS.start(NSStart());
110 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
111}
112
113private function f_init_gsup(charstring id) runs on test_CT {
114 id := id & "-GSUP";
115 var GsupOps ops := {
116 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
117 };
118
119 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
120 vc_GSUP := GSUP_Emulation_CT.create(id);
121
122 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
123 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
124 /* we use this hack to get events like ASP_IPA_EVENT_UP */
125 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
126
127 vc_GSUP.start(GSUP_Emulation.main(ops, id));
128 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
129
130 /* wait for incoming connection to GSUP port before proceeding */
131 timer T := 10.0;
132 T.start;
133 alt {
134 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
135 [] T.timeout {
136 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200137 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100138 }
139 }
140}
141
Harald Welteeded9ad2018-02-17 20:57:34 +0100142private function f_init_gtp(charstring id) runs on test_CT {
143 id := id & "-GTP";
144
145 var GtpEmulationCfg gtp_cfg := {
146 gtpc_bind_ip := mp_ggsn_ip,
147 gtpc_bind_port := GTP1C_PORT,
148 gtpu_bind_ip := mp_ggsn_ip,
149 gtpu_bind_port := GTP1U_PORT,
150 sgsn_role := false
151 };
152
153 vc_GTP := GTP_Emulation_CT.create(id);
154 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
155}
156
Harald Weltebd194722018-02-16 22:11:08 +0100157private function f_init_vty() runs on test_CT {
158 map(self:SGSNVTY, system:SGSNVTY);
159 f_vty_set_prompts(SGSNVTY);
160 f_vty_transceive(SGSNVTY, "enable");
161 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
162}
163
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200164private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
165 if (enable) {
166 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
167 } else {
168 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
169 }
170}
171
Harald Weltebd194722018-02-16 22:11:08 +0100172
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100173function f_init(BcdMccMnc mcc_mnc := '26242F'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100174 if (g_initialized == true) {
175 return;
176 }
177 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100178 g_gb[0].cfg := {
179 nsei := 96,
180 bvci := 196,
181 cell_id := {
182 ra_id := {
183 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100184 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100185 rac := 0
186 },
187 cell_id := 20960
188 },
189 sgsn_role := false
190 };
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");
Daniel Willmannafce8662018-07-06 23:11:32 +0200243 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100244 }
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));
Daniel Willmannafce8662018-07-06 23:11:32 +0200388 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100389 }
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");
Daniel Willmannafce8662018-07-06 23:11:32 +0200394 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100395 }
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");
Daniel Willmannafce8662018-07-06 23:11:32 +0200400 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100401 }
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");
Daniel Willmannafce8662018-07-06 23:11:32 +0200417 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100418 }
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");
Daniel Willmannafce8662018-07-06 23:11:32 +0200423 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100424 }
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");
Daniel Willmannafce8662018-07-06 23:11:32 +0200543 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100544 }
545 }
546}
547testcase TC_attach_auth_id_timeout() runs on test_CT {
548 var BSSGP_ConnHdlr vc_conn;
549 f_init();
550 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb[0], 2, 40.0);
551 vc_conn.done;
552}
553
554/* HLR never responds to SAI REQ, expect ATTACH REJECT */
555private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100556 var RoutingAreaIdentificationV old_ra := f_random_RAI();
557
Harald Welte23178c52018-02-17 09:36:33 +0100558 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100559 alt {
560 [] as_mm_identity();
561 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
562 }
563 /* don't send SAI-response from HLR */
Harald Welte1967d472018-02-16 21:54:21 +0100564 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100565 setverdict(pass);
566}
567testcase TC_attach_auth_sai_timeout() runs on test_CT {
568 var BSSGP_ConnHdlr vc_conn;
569 f_init();
570 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb[0], 3);
571 vc_conn.done;
572}
573
Harald Weltefe253882018-02-17 09:25:00 +0100574/* HLR rejects SAI, expect ATTACH REJECT */
575private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100576 var RoutingAreaIdentificationV old_ra := f_random_RAI();
577
Harald Welte23178c52018-02-17 09:36:33 +0100578 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100579 alt {
580 [] as_mm_identity();
581 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
582 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
583 }
584 }
585 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
586 setverdict(pass);
587}
588testcase TC_attach_auth_sai_reject() runs on test_CT {
589 var BSSGP_ConnHdlr vc_conn;
590 f_init();
Harald Welteb7c14e92018-02-17 09:29:16 +0100591 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb[0], 4);
Harald Weltefe253882018-02-17 09:25:00 +0100592 vc_conn.done;
593}
594
Harald Welte5b7c8122018-02-16 21:48:17 +0100595/* HLR never responds to UL REQ, expect ATTACH REJECT */
596private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100597 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100598 var RoutingAreaIdentificationV old_ra := f_random_RAI();
599
Harald Welte23178c52018-02-17 09:36:33 +0100600 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100601 f_gmm_auth();
602 /* Expect MSC to perform LU with HLR */
603 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
604 /* Never follow-up with ISD_REQ or UL_RES */
605 alt {
Harald Welte1967d472018-02-16 21:54:21 +0100606 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100607 setverdict(pass);
608 }
Harald Welte04683d02018-02-16 22:43:45 +0100609 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
610 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100611 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200612 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100613 }
614 }
615}
616testcase TC_attach_gsup_lu_timeout() runs on test_CT {
617 var BSSGP_ConnHdlr vc_conn;
618 f_init();
619 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100620 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb[0], 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100621 vc_conn.done;
622}
623
Harald Welteb7c14e92018-02-17 09:29:16 +0100624/* HLR rejects UL REQ, expect ATTACH REJECT */
625private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
626 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100627 var RoutingAreaIdentificationV old_ra := f_random_RAI();
628
Harald Welte23178c52018-02-17 09:36:33 +0100629 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100630 f_gmm_auth();
631 /* Expect MSC to perform LU with HLR */
632 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
633 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
634 }
635 alt {
636 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
637 setverdict(pass);
638 }
639 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
640 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
641 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200642 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100643 }
644 }
645}
646testcase TC_attach_gsup_lu_reject() runs on test_CT {
647 var BSSGP_ConnHdlr vc_conn;
648 f_init();
649 f_sleep(1.0);
650 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb[0], 6);
651 vc_conn.done;
652}
653
654
Harald Welte3823e2e2018-02-16 21:53:48 +0100655/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
656private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100657 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100658 var RoutingAreaIdentificationV old_ra := f_random_RAI();
659
Harald Welte23178c52018-02-17 09:36:33 +0100660 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100661 f_gmm_auth();
662 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100663 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100664
Harald Welte04683d02018-02-16 22:43:45 +0100665 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
666 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
667 }
Harald Welte3823e2e2018-02-16 21:53:48 +0100668 BSSGP.send(ts_GMM_ATTACH_COMPL);
669 setverdict(pass);
670}
Harald Welte3823e2e2018-02-16 21:53:48 +0100671testcase TC_attach_combined() runs on test_CT {
672 var BSSGP_ConnHdlr vc_conn;
673 f_init();
674 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100675 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb[0], 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100676 vc_conn.done;
677}
678
Harald Welte76dee092018-02-16 22:12:59 +0100679/* Attempt of GPRS ATTACH in 'accept all' mode */
680private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100681 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100682 var RoutingAreaIdentificationV old_ra := f_random_RAI();
683
684 g_pars.net.expect_auth := false;
685
Harald Welte23178c52018-02-17 09:36:33 +0100686 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100687 f_gmm_auth();
Harald Welte04683d02018-02-16 22:43:45 +0100688 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
689 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
690 }
Harald Welte76dee092018-02-16 22:12:59 +0100691 BSSGP.send(ts_GMM_ATTACH_COMPL);
692 setverdict(pass);
693}
694testcase TC_attach_accept_all() runs on test_CT {
695 var BSSGP_ConnHdlr vc_conn;
696 f_init();
697 f_sleep(1.0);
698 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Harald Welteb7c14e92018-02-17 09:29:16 +0100699 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 8);
Harald Welte76dee092018-02-16 22:12:59 +0100700 vc_conn.done;
701}
Harald Welte5b7c8122018-02-16 21:48:17 +0100702
Harald Welteb2124b22018-02-16 22:26:56 +0100703/* Attempt of GPRS ATTACH in 'accept all' mode */
704private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100705 var RoutingAreaIdentificationV old_ra := f_random_RAI();
706
707 /* Simulate a foreign IMSI */
708 g_pars.imsi := '001010123456789'H;
709 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
710
711 g_pars.net.expect_auth := false;
712
Harald Welte23178c52018-02-17 09:36:33 +0100713 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100714 alt {
715 [] as_mm_identity();
716 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
717 setverdict(pass);
718 }
719 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
720 setverdict(pass);
721 }
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200722 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
723 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200724 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200725 }
Harald Welteb2124b22018-02-16 22:26:56 +0100726 }
727}
728testcase TC_attach_closed() runs on test_CT {
729 var BSSGP_ConnHdlr vc_conn;
730 f_init();
731 f_sleep(1.0);
732 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
733 /* test with foreign IMSI: Must Reject */
Harald Welteb7c14e92018-02-17 09:29:16 +0100734 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100735 vc_conn.done;
736 /* test with home IMSI: Must Accept */
Harald Welteb7c14e92018-02-17 09:29:16 +0100737 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100738 vc_conn.done;
739}
740
Harald Welte04683d02018-02-16 22:43:45 +0100741/* Routing Area Update from Unknown TLLI -> REJECT */
742private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100743 var RoutingAreaIdentificationV old_ra := f_random_RAI();
744
Harald Welte23178c52018-02-17 09:36:33 +0100745 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 +0100746 alt {
747 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
748 setverdict(pass);
749 }
750 /* FIXME: Expect XID RESET? */
751 [] BSSGP.receive { repeat; }
752 }
753}
754testcase TC_rau_unknown() runs on test_CT {
755 var BSSGP_ConnHdlr vc_conn;
756 f_init();
757 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100758 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb[0], 11);
Harald Welte04683d02018-02-16 22:43:45 +0100759 vc_conn.done;
760}
761
Harald Welte91636de2018-02-17 10:16:14 +0100762private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
763 var BssgpDecoded bd;
764
765 /* first perform regular attach */
766 f_TC_attach(id);
767
768 /* then send RAU */
769 BSSGP.send(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit));
770 alt {
771 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
772 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept);
Alexander Couzens80ec1ea2018-05-12 16:44:36 +0200773 BSSGP.send(ts_GMM_RAU_COMPL);
Harald Welte91636de2018-02-17 10:16:14 +0100774 setverdict(pass);
775 }
776 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
777 setverdict(fail, "Unexpected RAU Reject");
Daniel Willmannafce8662018-07-06 23:11:32 +0200778 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100779 }
780 [] BSSGP.receive { repeat; }
781 }
782}
783testcase TC_attach_rau() runs on test_CT {
784 var BSSGP_ConnHdlr vc_conn;
785 f_init();
786 f_sleep(1.0);
787 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb[0], 12);
788 vc_conn.done;
789}
Harald Welte04683d02018-02-16 22:43:45 +0100790
Harald Welte6abb9fe2018-02-17 15:24:48 +0100791/* general GPRS DETACH helper */
792function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge) runs on BSSGP_ConnHdlr {
793 var BssgpDecoded bd;
794 timer T := 5.0;
795 BSSGP.send(ts_GMM_DET_REQ_MO(detach_type, power_off));
796 if (expect_purge) {
797 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
798 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
799 }
800 T.start;
801 alt {
802 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
803 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200804 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100805 }
806 [power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
807 g_pars.ra := omit;
808 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200809 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100810 /* TODO: check if any PDP contexts are deactivated on network side? */
811 }
812 [power_off] T.timeout {
813 setverdict(pass);
814 }
815 [not power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
816 g_pars.ra := omit;
817 setverdict(pass);
818 /* TODO: check if any PDP contexts are deactivated on network side? */
819 }
820 [] BSSGP.receive { repeat; }
821 }
822}
823
824/* IMSI DETACH (non-power-off) for unknown TLLI */
825private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
826 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
827}
828testcase TC_detach_unknown_nopoweroff() runs on test_CT {
829 var BSSGP_ConnHdlr vc_conn;
830 f_init();
831 f_sleep(1.0);
832 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb[0], 13);
833 vc_conn.done;
834}
835
836/* IMSI DETACH (power-off) for unknown TLLI */
837private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
838 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
839}
840testcase TC_detach_unknown_poweroff() runs on test_CT {
841 var BSSGP_ConnHdlr vc_conn;
842 f_init();
843 f_sleep(1.0);
844 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb[0], 14);
845 vc_conn.done;
846}
847
848/* IMSI DETACH (non-power-off) for known TLLI */
849private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
850 /* first perform regular attach */
851 f_TC_attach(id);
852
853 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
854}
855testcase TC_detach_nopoweroff() runs on test_CT {
856 var BSSGP_ConnHdlr vc_conn;
857 f_init();
858 f_sleep(1.0);
859 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb[0], 15);
860 vc_conn.done;
861}
862
863/* IMSI DETACH (power-off) for known TLLI */
864private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
865 /* first perform regular attach */
866 f_TC_attach(id);
867
868 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
869}
870testcase TC_detach_poweroff() runs on test_CT {
871 var BSSGP_ConnHdlr vc_conn;
872 f_init();
873 f_sleep(1.0);
874 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb[0], 16);
875 vc_conn.done;
876}
877
Harald Welteeded9ad2018-02-17 20:57:34 +0100878type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100879 BIT3 tid, /* L3 Transaction ID */
880 BIT4 nsapi, /* SNDCP NSAPI */
881 BIT4 sapi, /* LLC SAPI */
882 QoSV qos, /* QoS parameters */
883 PDPAddressV addr, /* IP address */
884 octetstring apn optional, /* APN name */
885 ProtocolConfigOptionsV pco optional, /* protoco config opts */
886 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100887 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100888 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100889
Harald Welte822f9102018-02-18 20:39:06 +0100890 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
891 OCT4 ggsn_tei_u, /* GGSN TEI User */
892 octetstring ggsn_ip_c, /* GGSN IP Control */
893 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200894 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100895
Harald Welte822f9102018-02-18 20:39:06 +0100896 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
897 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
898 octetstring sgsn_ip_c optional, /* SGSN IP Control */
899 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100900};
901
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100902
903private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
904 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
905 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
906 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
907 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
908 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
909 f_gtp_register_teid(apars.ggsn_tei_c);
910 f_gtp_register_teid(apars.ggsn_tei_u);
911}
912
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200913function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100914 var boolean exp_rej := ispresent(apars.exp_rej_cause);
915 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200916 var template Recovery_gtpc recovery := omit;
917
918 if (send_recovery) {
919 recovery := ts_Recovery(apars.ggsn_restart_ctr);
920 }
Harald Welteeded9ad2018-02-17 20:57:34 +0100921
922 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
923 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100924 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
925 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
926 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
927 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
928 apars.sgsn_tei_c, apars.gtp_resp_cause,
929 apars.ggsn_tei_c, apars.ggsn_tei_u,
930 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200931 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
932 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +0100933 }
934 alt {
Harald Welte28307082018-02-18 12:14:18 +0100935 [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 +0100936 setverdict(pass);
937 }
Harald Welte28307082018-02-18 12:14:18 +0100938 [exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100939 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +0200940 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +0100941 }
Harald Welte28307082018-02-18 12:14:18 +0100942 [not exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100943 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +0200944 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +0100945 }
Harald Welte28307082018-02-18 12:14:18 +0100946 [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 +0100947 setverdict(pass);
948 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100949 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +0100950 }
951}
952
Harald Welte6f203162018-02-18 22:04:55 +0100953function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
954 var boolean exp_rej := ispresent(apars.exp_rej_cause);
955 var Gtp1cUnitdata g_ud;
956
957 BSSGP.send(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
958 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
959 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
960 BSSGP.clear;
961 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
962 }
963 alt {
964 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
965 setverdict(pass);
966 }
967 [] as_xid(apars);
968 }
969}
970
Pau Espin Pedrol482dde62018-07-18 13:47:42 +0200971function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +0100972 var Gtp1cUnitdata g_ud;
973 var integer seq_nr := 23;
974 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
975
976 BSSGP.clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +0200977 if (error_ind) {
978 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
979 } else {
980 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
981 }
982 alt {
Pau Espin Pedrolbcddb8c2018-07-16 12:28:03 +0200983 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Harald Welte57b9b7f2018-02-18 22:28:13 +0100984 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
985 }
Pau Espin Pedrol482dde62018-07-18 13:47:42 +0200986 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) { }
Harald Welte57b9b7f2018-02-18 22:28:13 +0100987 }
988}
989
Harald Welte6f203162018-02-18 22:04:55 +0100990
Harald Welteeded9ad2018-02-17 20:57:34 +0100991/* Table 10.5.156/3GPP TS 24.008 */
992template (value) QoSV t_QosDefault := {
993 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
994 delayClass := '100'B, /* best effort */
995 spare1 := '00'B,
996 precedenceClass := '010'B, /* normal */
997 spare2 := '0'B,
998 peakThroughput := '0000'B, /* subscribed */
999 meanThroughput := '00000'B, /* subscribed */
1000 spare3 := '000'B,
1001 deliverErroneusSDU := omit,
1002 deliveryOrder := omit,
1003 trafficClass := omit,
1004 maxSDUSize := omit,
1005 maxBitrateUplink := omit,
1006 maxBitrateDownlink := omit,
1007 sduErrorRatio := omit,
1008 residualBER := omit,
1009 trafficHandlingPriority := omit,
1010 transferDelay := omit,
1011 guaranteedBitRateUplink := omit,
1012 guaranteedBitRateDownlink := omit,
1013 sourceStatisticsDescriptor := omit,
1014 signallingIndication := omit,
1015 spare4 := omit,
1016 maxBitrateDownlinkExt := omit,
1017 guaranteedBitRateDownlinkExt := omit,
1018 maxBitrateUplinkExt := omit,
1019 guaranteedBitRateUplinkExt := omit,
1020 maxBitrateDownlinkExt2 := omit,
1021 guaranteedBitRateDownlinkExt2 := omit,
1022 maxBitrateUplinkExt2 := omit,
1023 guaranteedBitRateUplinkExt2 := omit
1024}
1025
1026/* 10.5.6.4 / 3GPP TS 24.008 */
1027template (value) PDPAddressV t_AddrIPv4dyn := {
1028 pdpTypeOrg := '0001'B, /* IETF */
1029 spare := '0000'B,
1030 pdpTypeNum := '21'O, /* IPv4 */
1031 addressInfo := omit
1032}
1033template (value) PDPAddressV t_AddrIPv6dyn := {
1034 pdpTypeOrg := '0001'B, /* IETF */
1035 spare := '0000'B,
1036 pdpTypeNum := '53'O, /* IPv6 */
1037 addressInfo := omit
1038}
1039
Harald Welte37692d82018-02-18 15:21:34 +01001040template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001041 tid := '000'B,
1042 nsapi := '0101'B, /* < 5 are reserved */
1043 sapi := '0011'B, /* 3/5/9/11 */
1044 qos := t_QosDefault,
1045 addr := t_AddrIPv4dyn,
1046 apn := omit,
1047 pco := omit,
1048 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001049 gtp_resp_cause := int2oct(128, 1),
1050 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001051
1052 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001053 ggsn_tei_c := f_rnd_octstring(4),
1054 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001055 ggsn_ip_c := f_inet_addr(ggsn_ip),
1056 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001057 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001058
Harald Welteeded9ad2018-02-17 20:57:34 +01001059 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001060 sgsn_tei_u := omit,
1061 sgsn_ip_c := omit,
1062 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001063}
1064
Harald Welte37692d82018-02-18 15:21:34 +01001065template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1066 connId := 1,
1067 remName := f_inet_ntoa(ip),
1068 remPort := GTP1U_PORT
1069}
1070
1071template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1072 connId := 1,
1073 remName := f_inet_ntoa(ip),
1074 remPort := GTP1C_PORT
1075}
1076
1077private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1078 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1079 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1080}
1081
1082private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
1083 [] BSSGP.receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
1084 repeat;
1085 }
1086}
1087
1088template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1089 pDU_SN_UNITDATA := {
1090 nsapi := nsapi,
1091 moreBit := ?,
1092 snPduType := '1'B,
1093 firstSegmentIndicator := ?,
1094 spareBit := ?,
1095 pcomp := ?,
1096 dcomp := ?,
1097 npduNumber := ?,
1098 segmentNumber := ?,
1099 npduNumberContinued := ?,
1100 dataSegmentSnUnitdataPdu := payload
1101 }
1102}
1103
1104/* simple case: single segment, no compression */
1105template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1106 pDU_SN_UNITDATA := {
1107 nsapi := nsapi,
1108 moreBit := '0'B,
1109 snPduType := '1'B,
1110 firstSegmentIndicator := '1'B,
1111 spareBit := '0'B,
1112 pcomp := '0000'B,
1113 dcomp := '0000'B,
1114 npduNumber := '0000'B,
1115 segmentNumber := '0000'B,
1116 npduNumberContinued := '00'O,
1117 dataSegmentSnUnitdataPdu := payload
1118 }
1119}
1120
1121/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1122private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1123 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1124 f_gtpu_send(apars, payload);
1125 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1126 alt {
1127 [] as_xid(apars);
1128 [] BSSGP.receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1129 }
1130}
1131
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001132/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001133private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1134 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1135 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1136 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
1137 BSSGP.send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001138 /* Expect PDU via GTP from SGSN on simulated GGSN */
1139 alt {
1140 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1141 }
1142}
1143
Harald Welteeded9ad2018-02-17 20:57:34 +01001144private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001145 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001146
1147 /* first perform regular attach */
1148 f_TC_attach(id);
1149
1150 f_pdp_ctx_act(apars);
1151}
1152testcase TC_attach_pdp_act() runs on test_CT {
1153 var BSSGP_ConnHdlr vc_conn;
1154 f_init();
1155 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1156 vc_conn.done;
1157}
Harald Welteb2124b22018-02-16 22:26:56 +01001158
Harald Welte835b15f2018-02-18 14:39:11 +01001159/* PDP Context activation for not-attached subscriber; expect fail */
1160private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001161 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welte835b15f2018-02-18 14:39:11 +01001162 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1163 apars.apn, apars.pco));
1164 alt {
1165 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
1166 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
1167 setverdict(pass);
1168 }
1169 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1170 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001171 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001172 }
1173 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
1174 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001175 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001176 }
1177 [] BSSGP.receive { repeat; }
1178 }
1179}
1180testcase TC_pdp_act_unattached() runs on test_CT {
1181 var BSSGP_ConnHdlr vc_conn;
1182 f_init();
1183 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1184 vc_conn.done;
1185}
1186
Harald Welte37692d82018-02-18 15:21:34 +01001187/* ATTACH + PDP CTX ACT + user plane traffic */
1188private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1189 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1190
1191 /* first perform regular attach */
1192 f_TC_attach(id);
1193 /* then activate PDP context */
1194 f_pdp_ctx_act(apars);
1195 /* then transceive a downlink PDU */
1196 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1197 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1198}
1199testcase TC_attach_pdp_act_user() runs on test_CT {
1200 var BSSGP_ConnHdlr vc_conn;
1201 f_init();
1202 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1203 vc_conn.done;
1204}
1205
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001206/* ATTACH + PDP CTX ACT; reject from GGSN */
1207private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1208 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1209
1210 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1211 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1212
1213 /* first perform regular attach */
1214 f_TC_attach(id);
1215 /* then activate PDP context */
1216 f_pdp_ctx_act(apars);
1217}
1218testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1219 var BSSGP_ConnHdlr vc_conn;
1220 f_init();
1221 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1222 vc_conn.done;
1223}
Harald Welte835b15f2018-02-18 14:39:11 +01001224
Harald Welte6f203162018-02-18 22:04:55 +01001225/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1226private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1227 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1228
1229 /* first perform regular attach */
1230 f_TC_attach(id);
1231 /* then activate PDP context */
1232 f_pdp_ctx_act(apars);
1233 /* then transceive a downlink PDU */
1234 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1235 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1236
1237 f_pdp_ctx_deact_mo(apars, '00'O);
1238}
1239testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1240 var BSSGP_ConnHdlr vc_conn;
1241 f_init();
1242 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1243 vc_conn.done;
1244}
1245
Harald Welte57b9b7f2018-02-18 22:28:13 +01001246/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1247private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1248 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1249
1250 /* first perform regular attach */
1251 f_TC_attach(id);
1252 /* then activate PDP context */
1253 f_pdp_ctx_act(apars);
1254 /* then transceive a downlink PDU */
1255 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1256 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1257
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001258 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001259}
1260testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1261 var BSSGP_ConnHdlr vc_conn;
1262 f_init();
1263 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1264 vc_conn.done;
1265}
1266
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001267/* ATTACH + ATTACH (2nd) */
1268private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1269 g_pars.t_guard := 5.0;
1270
1271 /* first perform regular attach */
1272 f_TC_attach(id);
1273
1274 /* second to perform regular attach */
1275 f_TC_attach(id);
1276}
1277
1278
1279testcase TC_attach_second_attempt() runs on test_CT {
1280 var BSSGP_ConnHdlr vc_conn;
1281 f_init();
1282 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1283 vc_conn.done;
1284}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001285
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001286private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001287 var Gtp1cUnitdata g_ud;
1288 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1289
1290 /* first perform regular attach */
1291 f_TC_attach(id);
1292 /* Activate a pdp context against the GGSN */
1293 f_pdp_ctx_act(apars);
1294 /* Wait to receive first echo request and send initial Restart counter */
1295 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1296 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1297 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1298 }
1299 /* Wait to receive second echo request and send incremented Restart
1300 counter. This will fake a restarted GGSN, and pdp ctx allocated
1301 should be released by SGSN */
1302 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1303 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1304 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1305 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1306 }
1307 var OCT1 cause_network_failure := int2oct(38, 1)
1308 alt {
1309 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
1310 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1311 setverdict(pass);
1312 }
1313 [] as_xid(apars);
1314 }
1315 setverdict(pass);
1316}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001317/* ATTACH + trigger Recovery procedure through EchoResp */
1318testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001319 var BSSGP_ConnHdlr vc_conn;
1320 g_use_echo := true
1321 f_init();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001322 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 +02001323 vc_conn.done;
1324 g_use_echo := false
1325}
1326
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001327private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1328 var Gtp1cUnitdata g_ud;
1329 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1330 var integer seq_nr := 23;
1331 var GtpPeer peer;
1332 /* first perform regular attach */
1333 f_TC_attach(id);
1334
1335 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1336 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1337 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1338 f_pdp_ctx_act(apars, true);
1339
1340 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1341/* received. */
1342 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1343
1344 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1345 would be great to have an active pdp context here before triggering
1346 Recovery, and making sure the the DEACT request is sent by the SGSN.
1347 */
1348
1349 /* Activate a pdp context against the GGSN, send incremented Recovery
1350 IE. This should trigger the recovery path, but still this specific
1351 CTX activation should work. */
1352 apars.exp_rej_cause := omit; /* default value for tests */
1353 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1354 f_pdp_ctx_act(apars, true);
1355
1356 setverdict(pass);
1357}
1358/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1359testcase TC_attach_restart_ctr_create() runs on test_CT {
1360 var BSSGP_ConnHdlr vc_conn;
1361 f_init();
1362 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb[0], 24, 30.0);
1363 vc_conn.done;
1364}
1365
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001366/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1367private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1368 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1369 var integer seq_nr := 23;
1370 var GtpPeer peer;
1371 var integer i;
1372
1373 /* first perform regular attach */
1374 f_TC_attach(id);
1375 /* then activate PDP context */
1376 f_pdp_ctx_act(apars);
1377
1378 BSSGP.clear;
1379 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1380 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1381
1382 for (i := 0; i < 5; i := i+1) {
1383 alt {
1384 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
1385 [] as_xid(apars);
1386 }
1387 }
1388
1389 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1390
1391 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1392 setverdict(pass);
1393}
1394testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1395 var BSSGP_ConnHdlr vc_conn;
1396 f_init();
1397 f_sleep(1.0);
1398 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb[0], 25, 60.0);
1399 vc_conn.done;
1400}
1401
Alexander Couzens5e307b42018-05-22 18:12:20 +02001402private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1403 /* MS: perform regular attach */
1404 f_TC_attach(id);
1405
1406 /* HLR: cancel the location request */
1407 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1408 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001409
1410 /* ensure no Detach Request got received */
1411 timer T := 5.0;
1412 T.start;
1413 alt {
1414 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
1415 T.stop;
1416 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001417 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001418 }
1419 [] T.timeout {
1420 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001421 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001422 }
1423 [] BSSGP.receive {
1424 repeat;
1425 }
1426 }
1427}
1428
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001429/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1430private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1431 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1432
1433 /* first perform regular attach */
1434 f_TC_attach(id);
1435 /* then activate PDP context */
1436 f_pdp_ctx_act(apars);
1437 /* then transceive a downlink PDU */
1438 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1439
1440 /* Send Error indication as response from upload PDU and expect deact towards MS */
1441 f_pdp_ctx_deact_mt(apars, true);
1442}
1443testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1444 var BSSGP_ConnHdlr vc_conn;
1445 f_init();
1446 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb[0], 26);
1447 vc_conn.done;
1448}
1449
Alexander Couzens5e307b42018-05-22 18:12:20 +02001450testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1451 /* MS <-> SGSN: GMM Attach
1452 * HLR -> SGSN: Cancel Location Request
1453 * HLR <- SGSN: Cancel Location Ack
1454 */
1455 var BSSGP_ConnHdlr vc_conn;
1456 f_init();
1457 f_sleep(1.0);
1458 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1459 vc_conn.done;
1460}
1461
1462
Alexander Couzensc87967a2018-05-22 16:09:54 +02001463private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1464 /* MS: perform regular attach */
1465 f_TC_attach(id);
1466
1467 /* HLR: cancel the location request */
1468 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1469 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1470 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1471
1472 /* MS: receive a Detach Request */
1473 BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1474 BSSGP.send(ts_GMM_DET_ACCEPT_MO);
1475
1476 setverdict(pass);
1477}
1478
1479testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1480 /* MS <-> SGSN: GMM Attach
1481 * HLR -> SGSN: Cancel Location Request
1482 * HLR <- SGSN: Cancel Location Ack
1483 * MS <- SGSN: Detach Request
1484 * SGSN-> MS: Detach Complete
1485 */
1486 var BSSGP_ConnHdlr vc_conn;
1487 f_init();
1488 f_sleep(1.0);
1489 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1490 vc_conn.done;
1491}
1492
1493
Alexander Couzens6c47f292018-05-22 17:09:49 +02001494private function f_hlr_location_cancel_request_unknown_subscriber(
1495 charstring id,
1496 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1497
1498 /* HLR: cancel the location request */
1499 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1500
1501 /* cause 2 = IMSI_UNKNOWN */
1502 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1503
1504 setverdict(pass);
1505}
1506
1507private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001508 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001509}
1510
1511testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1512 /* HLR -> SGSN: Cancel Location Request
1513 * HLR <- SGSN: Cancel Location Error
1514 */
1515
1516 var BSSGP_ConnHdlr vc_conn;
1517 f_init();
1518 f_sleep(1.0);
1519 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1520 vc_conn.done;
1521}
1522
1523private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001524 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001525}
1526
1527testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1528 /* HLR -> SGSN: Cancel Location Request
1529 * HLR <- SGSN: Cancel Location Error
1530 */
1531
1532 var BSSGP_ConnHdlr vc_conn;
1533 f_init();
1534 f_sleep(1.0);
1535 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1536 vc_conn.done;
1537}
1538
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001539private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1540 f_TC_attach(id);
1541 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1542}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001543
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001544testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1545 /* MS <-> SGSN: Attach
1546 * MS -> SGSN: Detach Req (Power off)
1547 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1548 */
1549 var BSSGP_ConnHdlr vc_conn;
1550 var integer id := 33;
1551 var charstring imsi := hex2str(f_gen_imsi(id));
1552
1553 f_init();
1554 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb[0], id);
1555 vc_conn.done;
1556
1557 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1558}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001559
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001560/* Attempt an attach, but loose the Identification Request (IMEI) */
1561private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1562 var integer count_req := 0;
1563 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1564
1565 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1566
1567 alt {
1568 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1569 /* break */
1570 }
1571 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1572 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1573 BSSGP.send(ts_GMM_ID_RESP(mi));
1574 repeat;
1575 }
1576 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1577 /* ignore ID REQ IMEI */
1578 count_req := count_req + 1;
1579 repeat;
1580 }
1581 }
1582 if (count_req != 5) {
1583 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001584 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001585 }
1586 setverdict(pass);
1587}
1588
1589testcase TC_attach_no_imei_response() runs on test_CT {
1590 /* MS -> SGSN: Attach Request IMSI
1591 * MS <- SGSN: Identity Request IMSI (optional)
1592 * MS -> SGSN: Identity Response IMSI (optional)
1593 * MS <- SGSN: Identity Request IMEI
1594 * MS -x SGSN: no response
1595 * MS <- SGSN: re-send: Identity Request IMEI 4x
1596 * MS <- SGSN: Attach Reject
1597 */
1598 var BSSGP_ConnHdlr vc_conn;
1599 f_init();
1600 f_sleep(1.0);
1601 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1602 vc_conn.done;
1603}
1604
Alexander Couzens53f20562018-06-12 16:24:12 +02001605/* Attempt an attach, but loose the Identification Request (IMSI) */
1606private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1607 var integer count_req := 0;
1608 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1609
1610 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1611 g_pars.p_tmsi := 'c0000035'O;
1612
1613 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1614
1615 alt {
1616 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1617 /* break */
1618 }
1619 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1620 /* ignore ID REQ IMSI */
1621 count_req := count_req + 1;
1622 repeat;
1623 }
1624 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1625 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1626 BSSGP.send(ts_GMM_ID_RESP(mi));
1627 repeat;
1628 }
1629 }
1630 if (count_req != 5) {
1631 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001632 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001633 }
1634 setverdict(pass);
1635}
1636
1637testcase TC_attach_no_imsi_response() runs on test_CT {
1638 /* MS -> SGSN: Attach Request TMSI (unknown)
1639 * MS <- SGSN: Identity Request IMEI (optional)
1640 * MS -> SGSN: Identity Response IMEI (optional)
1641 * MS <- SGSN: Identity Request IMSI
1642 * MS -x SGSN: no response
1643 * MS <- SGSN: re-send: Identity Request IMSI 4x
1644 * MS <- SGSN: Attach Reject
1645 */
1646 var BSSGP_ConnHdlr vc_conn;
1647 f_init();
1648 f_sleep(1.0);
1649 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1650 vc_conn.done;
1651}
1652
Alexander Couzenscf818962018-06-05 18:00:00 +02001653private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1654 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1655}
1656
1657testcase TC_attach_check_subscriber_list() runs on test_CT {
1658 /* MS <-> SGSN: Attach
1659 * VTY -> SGSN: Check if MS is in subscriber cache
1660 */
1661 var BSSGP_ConnHdlr vc_conn;
1662 var integer id := 34;
1663 var charstring imsi := hex2str(f_gen_imsi(id));
1664
1665 f_init();
1666 f_sleep(1.0);
1667 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], id);
1668 vc_conn.done;
1669
1670 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1671 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1672}
1673
Alexander Couzensf9858652018-06-07 16:14:53 +02001674private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1675 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1676 var BssgpDecoded bd;
1677
1678 /* unregister the old IMSI */
1679 f_bssgp_client_unregister(g_pars.imsi);
1680 /* Simulate a foreign IMSI */
1681 g_pars.imsi := '001010123456789'H;
1682 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
1683
1684 /* there is no auth */
1685 g_pars.net.expect_auth := false;
1686
1687 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
1688 f_gmm_auth();
1689 alt {
1690 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1691 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001692 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001693 }
1694 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
1695 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1696 BSSGP.send(ts_GMM_ATTACH_COMPL);
1697 setverdict(pass);
1698 }
1699 }
1700}
1701testcase TC_attach_closed_add_vty() runs on test_CT {
1702 /* VTY-> SGSN: policy close
1703 * MS -> SGSN: Attach Request
1704 * MS <- SGSN: Identity Request IMSI
1705 * MS -> SGSN: Identity Response IMSI
1706 * MS <- SGSN: Attach Reject
1707 * VTY-> SGSN: policy imsi-acl add IMSI
1708 * MS -> SGSN: Attach Request
1709 * MS <- SGSN: Identity Request IMSI
1710 * MS -> SGSN: Identity Response IMSI
1711 * MS <- SGSN: Identity Request IMEI
1712 * MS -> SGSN: Identity Response IMEI
1713 * MS <- SGSN: Attach Accept
1714 */
1715 var BSSGP_ConnHdlr vc_conn;
1716 f_init();
1717 f_sleep(1.0);
1718 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1719 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
1720 /* test with foreign IMSI: Must Reject */
1721 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
1722 vc_conn.done;
1723 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456789");
1724 /* test with same IMSI: Must Accept */
1725 vc_conn := f_start_handler(refers(f_TC_attach_closed_imsi_added), testcasename(), g_gb[0], 10);
1726 vc_conn.done;
1727}
1728
Alexander Couzens0085bd72018-06-12 19:08:44 +02001729/* Attempt an attach, but never answer a Attach Complete */
1730private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1731 var integer count_req := 0;
1732
1733 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1734 f_gmm_auth();
1735
1736 alt {
1737 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1738 /* break */
1739 }
1740 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
1741 /* ignore */
1742 count_req := count_req + 1;
1743 repeat;
1744 }
1745 }
1746 if (count_req != 5) {
1747 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001748 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001749 }
1750 setverdict(pass);
1751}
1752
1753testcase TC_attach_check_complete_resend() runs on test_CT {
1754 /* MS -> SGSN: Attach Request IMSI
1755 * MS <- SGSN: Identity Request *
1756 * MS -> SGSN: Identity Response *
1757 * MS <- SGSN: Attach Complete 5x
1758 */
1759 var BSSGP_ConnHdlr vc_conn;
1760 f_init();
1761 f_sleep(1.0);
1762 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb[0], 36, 60.0);
1763 vc_conn.done;
1764}
1765
Harald Welte5ac31492018-02-15 20:39:13 +01001766control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001767 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001768 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001769 execute( TC_attach_umts_aka_umts_res() );
1770 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001771 execute( TC_attach_auth_id_timeout() );
1772 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001773 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001774 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001775 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001776 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001777 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001778 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001779 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001780 execute( TC_attach_no_imsi_response() );
Alexander Couzensf9858652018-06-07 16:14:53 +02001781 execute( TC_attach_closed_add_vty(), 10.0 );
Alexander Couzenscf818962018-06-05 18:00:00 +02001782 execute( TC_attach_check_subscriber_list(), 10.0 );
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001783 execute( TC_attach_detach_check_subscriber_list(), 10.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02001784 execute( TC_attach_check_complete_resend() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001785 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001786 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1787 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1788 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001789 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001790 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001791 execute( TC_detach_unknown_nopoweroff() );
1792 execute( TC_detach_unknown_poweroff() );
1793 execute( TC_detach_nopoweroff() );
1794 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001795 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001796 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001797 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001798 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001799 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001800 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001801 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001802 execute( TC_attach_restart_ctr_echo() );
1803 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001804 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001805 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Harald Welte5ac31492018-02-15 20:39:13 +01001806}
Harald Welte96a33b02018-02-04 10:36:22 +01001807
1808
1809
1810}