blob: ce796e827bd3f836212d3b3ccf087c5c10302cfa [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 }
Alexander Couzens5e71c142018-08-07 17:21:24 +0200982
983 timer T := 5.0;
984 T.start;
985
Pau Espin Pedrol482dde62018-07-18 13:47:42 +0200986 alt {
Pau Espin Pedrolbcddb8c2018-07-16 12:28:03 +0200987 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Harald Welte57b9b7f2018-02-18 22:28:13 +0100988 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
989 }
Alexander Couzens5e71c142018-08-07 17:21:24 +0200990 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
991 repeat;
992 }
993 [] T.timeout {
994 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
995 }
Harald Welte57b9b7f2018-02-18 22:28:13 +0100996 }
997}
998
Harald Welte6f203162018-02-18 22:04:55 +0100999
Harald Welteeded9ad2018-02-17 20:57:34 +01001000/* Table 10.5.156/3GPP TS 24.008 */
1001template (value) QoSV t_QosDefault := {
1002 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1003 delayClass := '100'B, /* best effort */
1004 spare1 := '00'B,
1005 precedenceClass := '010'B, /* normal */
1006 spare2 := '0'B,
1007 peakThroughput := '0000'B, /* subscribed */
1008 meanThroughput := '00000'B, /* subscribed */
1009 spare3 := '000'B,
1010 deliverErroneusSDU := omit,
1011 deliveryOrder := omit,
1012 trafficClass := omit,
1013 maxSDUSize := omit,
1014 maxBitrateUplink := omit,
1015 maxBitrateDownlink := omit,
1016 sduErrorRatio := omit,
1017 residualBER := omit,
1018 trafficHandlingPriority := omit,
1019 transferDelay := omit,
1020 guaranteedBitRateUplink := omit,
1021 guaranteedBitRateDownlink := omit,
1022 sourceStatisticsDescriptor := omit,
1023 signallingIndication := omit,
1024 spare4 := omit,
1025 maxBitrateDownlinkExt := omit,
1026 guaranteedBitRateDownlinkExt := omit,
1027 maxBitrateUplinkExt := omit,
1028 guaranteedBitRateUplinkExt := omit,
1029 maxBitrateDownlinkExt2 := omit,
1030 guaranteedBitRateDownlinkExt2 := omit,
1031 maxBitrateUplinkExt2 := omit,
1032 guaranteedBitRateUplinkExt2 := omit
1033}
1034
1035/* 10.5.6.4 / 3GPP TS 24.008 */
1036template (value) PDPAddressV t_AddrIPv4dyn := {
1037 pdpTypeOrg := '0001'B, /* IETF */
1038 spare := '0000'B,
1039 pdpTypeNum := '21'O, /* IPv4 */
1040 addressInfo := omit
1041}
1042template (value) PDPAddressV t_AddrIPv6dyn := {
1043 pdpTypeOrg := '0001'B, /* IETF */
1044 spare := '0000'B,
1045 pdpTypeNum := '53'O, /* IPv6 */
1046 addressInfo := omit
1047}
1048
Harald Welte37692d82018-02-18 15:21:34 +01001049template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001050 tid := '000'B,
1051 nsapi := '0101'B, /* < 5 are reserved */
1052 sapi := '0011'B, /* 3/5/9/11 */
1053 qos := t_QosDefault,
1054 addr := t_AddrIPv4dyn,
1055 apn := omit,
1056 pco := omit,
1057 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001058 gtp_resp_cause := int2oct(128, 1),
1059 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001060
1061 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001062 ggsn_tei_c := f_rnd_octstring(4),
1063 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001064 ggsn_ip_c := f_inet_addr(ggsn_ip),
1065 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001066 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001067
Harald Welteeded9ad2018-02-17 20:57:34 +01001068 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001069 sgsn_tei_u := omit,
1070 sgsn_ip_c := omit,
1071 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001072}
1073
Harald Welte37692d82018-02-18 15:21:34 +01001074template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1075 connId := 1,
1076 remName := f_inet_ntoa(ip),
1077 remPort := GTP1U_PORT
1078}
1079
1080template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1081 connId := 1,
1082 remName := f_inet_ntoa(ip),
1083 remPort := GTP1C_PORT
1084}
1085
1086private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1087 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1088 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1089}
1090
1091private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
1092 [] BSSGP.receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
1093 repeat;
1094 }
1095}
1096
1097template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1098 pDU_SN_UNITDATA := {
1099 nsapi := nsapi,
1100 moreBit := ?,
1101 snPduType := '1'B,
1102 firstSegmentIndicator := ?,
1103 spareBit := ?,
1104 pcomp := ?,
1105 dcomp := ?,
1106 npduNumber := ?,
1107 segmentNumber := ?,
1108 npduNumberContinued := ?,
1109 dataSegmentSnUnitdataPdu := payload
1110 }
1111}
1112
1113/* simple case: single segment, no compression */
1114template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1115 pDU_SN_UNITDATA := {
1116 nsapi := nsapi,
1117 moreBit := '0'B,
1118 snPduType := '1'B,
1119 firstSegmentIndicator := '1'B,
1120 spareBit := '0'B,
1121 pcomp := '0000'B,
1122 dcomp := '0000'B,
1123 npduNumber := '0000'B,
1124 segmentNumber := '0000'B,
1125 npduNumberContinued := '00'O,
1126 dataSegmentSnUnitdataPdu := payload
1127 }
1128}
1129
1130/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1131private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1132 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1133 f_gtpu_send(apars, payload);
1134 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1135 alt {
1136 [] as_xid(apars);
1137 [] BSSGP.receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1138 }
1139}
1140
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001141/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001142private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1143 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1144 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1145 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
1146 BSSGP.send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001147 /* Expect PDU via GTP from SGSN on simulated GGSN */
1148 alt {
1149 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1150 }
1151}
1152
Harald Welteeded9ad2018-02-17 20:57:34 +01001153private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001154 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001155
1156 /* first perform regular attach */
1157 f_TC_attach(id);
1158
1159 f_pdp_ctx_act(apars);
1160}
1161testcase TC_attach_pdp_act() runs on test_CT {
1162 var BSSGP_ConnHdlr vc_conn;
1163 f_init();
1164 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1165 vc_conn.done;
1166}
Harald Welteb2124b22018-02-16 22:26:56 +01001167
Harald Welte835b15f2018-02-18 14:39:11 +01001168/* PDP Context activation for not-attached subscriber; expect fail */
1169private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001170 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welte835b15f2018-02-18 14:39:11 +01001171 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1172 apars.apn, apars.pco));
1173 alt {
1174 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
1175 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
1176 setverdict(pass);
1177 }
1178 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1179 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001180 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001181 }
1182 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
1183 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001184 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001185 }
1186 [] BSSGP.receive { repeat; }
1187 }
1188}
1189testcase TC_pdp_act_unattached() runs on test_CT {
1190 var BSSGP_ConnHdlr vc_conn;
1191 f_init();
1192 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1193 vc_conn.done;
1194}
1195
Harald Welte37692d82018-02-18 15:21:34 +01001196/* ATTACH + PDP CTX ACT + user plane traffic */
1197private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1198 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1199
1200 /* first perform regular attach */
1201 f_TC_attach(id);
1202 /* then activate PDP context */
1203 f_pdp_ctx_act(apars);
1204 /* then transceive a downlink PDU */
1205 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1206 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1207}
1208testcase TC_attach_pdp_act_user() runs on test_CT {
1209 var BSSGP_ConnHdlr vc_conn;
1210 f_init();
1211 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1212 vc_conn.done;
1213}
1214
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001215/* ATTACH + PDP CTX ACT; reject from GGSN */
1216private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1217 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1218
1219 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1220 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1221
1222 /* first perform regular attach */
1223 f_TC_attach(id);
1224 /* then activate PDP context */
1225 f_pdp_ctx_act(apars);
1226}
1227testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1228 var BSSGP_ConnHdlr vc_conn;
1229 f_init();
1230 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1231 vc_conn.done;
1232}
Harald Welte835b15f2018-02-18 14:39:11 +01001233
Harald Welte6f203162018-02-18 22:04:55 +01001234/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1235private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1236 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1237
1238 /* first perform regular attach */
1239 f_TC_attach(id);
1240 /* then activate PDP context */
1241 f_pdp_ctx_act(apars);
1242 /* then transceive a downlink PDU */
1243 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1244 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1245
1246 f_pdp_ctx_deact_mo(apars, '00'O);
1247}
1248testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1249 var BSSGP_ConnHdlr vc_conn;
1250 f_init();
1251 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1252 vc_conn.done;
1253}
1254
Harald Welte57b9b7f2018-02-18 22:28:13 +01001255/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1256private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1257 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1258
1259 /* first perform regular attach */
1260 f_TC_attach(id);
1261 /* then activate PDP context */
1262 f_pdp_ctx_act(apars);
1263 /* then transceive a downlink PDU */
1264 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1265 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1266
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001267 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001268}
1269testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1270 var BSSGP_ConnHdlr vc_conn;
1271 f_init();
1272 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1273 vc_conn.done;
1274}
1275
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001276/* ATTACH + ATTACH (2nd) */
1277private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1278 g_pars.t_guard := 5.0;
1279
1280 /* first perform regular attach */
1281 f_TC_attach(id);
1282
1283 /* second to perform regular attach */
1284 f_TC_attach(id);
1285}
1286
1287
1288testcase TC_attach_second_attempt() runs on test_CT {
1289 var BSSGP_ConnHdlr vc_conn;
1290 f_init();
1291 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1292 vc_conn.done;
1293}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001294
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001295private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001296 var Gtp1cUnitdata g_ud;
1297 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1298
1299 /* first perform regular attach */
1300 f_TC_attach(id);
1301 /* Activate a pdp context against the GGSN */
1302 f_pdp_ctx_act(apars);
1303 /* Wait to receive first echo request and send initial Restart counter */
1304 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1305 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1306 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1307 }
1308 /* Wait to receive second echo request and send incremented Restart
1309 counter. This will fake a restarted GGSN, and pdp ctx allocated
1310 should be released by SGSN */
1311 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1312 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1313 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1314 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1315 }
1316 var OCT1 cause_network_failure := int2oct(38, 1)
1317 alt {
1318 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
1319 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1320 setverdict(pass);
1321 }
1322 [] as_xid(apars);
1323 }
1324 setverdict(pass);
1325}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001326/* ATTACH + trigger Recovery procedure through EchoResp */
1327testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001328 var BSSGP_ConnHdlr vc_conn;
1329 g_use_echo := true
1330 f_init();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001331 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 +02001332 vc_conn.done;
1333 g_use_echo := false
1334}
1335
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001336private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1337 var Gtp1cUnitdata g_ud;
1338 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1339 var integer seq_nr := 23;
1340 var GtpPeer peer;
1341 /* first perform regular attach */
1342 f_TC_attach(id);
1343
1344 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1345 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1346 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1347 f_pdp_ctx_act(apars, true);
1348
1349 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1350/* received. */
1351 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1352
1353 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1354 would be great to have an active pdp context here before triggering
1355 Recovery, and making sure the the DEACT request is sent by the SGSN.
1356 */
1357
1358 /* Activate a pdp context against the GGSN, send incremented Recovery
1359 IE. This should trigger the recovery path, but still this specific
1360 CTX activation should work. */
1361 apars.exp_rej_cause := omit; /* default value for tests */
1362 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1363 f_pdp_ctx_act(apars, true);
1364
1365 setverdict(pass);
1366}
1367/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1368testcase TC_attach_restart_ctr_create() runs on test_CT {
1369 var BSSGP_ConnHdlr vc_conn;
1370 f_init();
1371 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb[0], 24, 30.0);
1372 vc_conn.done;
1373}
1374
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001375/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1376private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1377 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1378 var integer seq_nr := 23;
1379 var GtpPeer peer;
1380 var integer i;
1381
1382 /* first perform regular attach */
1383 f_TC_attach(id);
1384 /* then activate PDP context */
1385 f_pdp_ctx_act(apars);
1386
1387 BSSGP.clear;
1388 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1389 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1390
1391 for (i := 0; i < 5; i := i+1) {
1392 alt {
1393 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
1394 [] as_xid(apars);
1395 }
1396 }
1397
1398 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1399
1400 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1401 setverdict(pass);
1402}
1403testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1404 var BSSGP_ConnHdlr vc_conn;
1405 f_init();
1406 f_sleep(1.0);
1407 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb[0], 25, 60.0);
1408 vc_conn.done;
1409}
1410
Alexander Couzens5e307b42018-05-22 18:12:20 +02001411private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1412 /* MS: perform regular attach */
1413 f_TC_attach(id);
1414
1415 /* HLR: cancel the location request */
1416 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1417 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001418
1419 /* ensure no Detach Request got received */
1420 timer T := 5.0;
1421 T.start;
1422 alt {
1423 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
1424 T.stop;
1425 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001426 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001427 }
1428 [] T.timeout {
1429 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001430 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001431 }
1432 [] BSSGP.receive {
1433 repeat;
1434 }
1435 }
1436}
1437
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001438/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1439private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1440 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1441
1442 /* first perform regular attach */
1443 f_TC_attach(id);
1444 /* then activate PDP context */
1445 f_pdp_ctx_act(apars);
1446 /* then transceive a downlink PDU */
1447 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1448
1449 /* Send Error indication as response from upload PDU and expect deact towards MS */
1450 f_pdp_ctx_deact_mt(apars, true);
1451}
1452testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1453 var BSSGP_ConnHdlr vc_conn;
1454 f_init();
1455 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb[0], 26);
1456 vc_conn.done;
1457}
1458
Alexander Couzens5e307b42018-05-22 18:12:20 +02001459testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1460 /* MS <-> SGSN: GMM Attach
1461 * HLR -> SGSN: Cancel Location Request
1462 * HLR <- SGSN: Cancel Location Ack
1463 */
1464 var BSSGP_ConnHdlr vc_conn;
1465 f_init();
1466 f_sleep(1.0);
1467 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1468 vc_conn.done;
1469}
1470
1471
Alexander Couzensc87967a2018-05-22 16:09:54 +02001472private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1473 /* MS: perform regular attach */
1474 f_TC_attach(id);
1475
1476 /* HLR: cancel the location request */
1477 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1478 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1479 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1480
1481 /* MS: receive a Detach Request */
1482 BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1483 BSSGP.send(ts_GMM_DET_ACCEPT_MO);
1484
1485 setverdict(pass);
1486}
1487
1488testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1489 /* MS <-> SGSN: GMM Attach
1490 * HLR -> SGSN: Cancel Location Request
1491 * HLR <- SGSN: Cancel Location Ack
1492 * MS <- SGSN: Detach Request
1493 * SGSN-> MS: Detach Complete
1494 */
1495 var BSSGP_ConnHdlr vc_conn;
1496 f_init();
1497 f_sleep(1.0);
1498 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1499 vc_conn.done;
1500}
1501
1502
Alexander Couzens6c47f292018-05-22 17:09:49 +02001503private function f_hlr_location_cancel_request_unknown_subscriber(
1504 charstring id,
1505 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1506
1507 /* HLR: cancel the location request */
1508 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1509
1510 /* cause 2 = IMSI_UNKNOWN */
1511 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1512
1513 setverdict(pass);
1514}
1515
1516private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001517 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001518}
1519
1520testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1521 /* HLR -> SGSN: Cancel Location Request
1522 * HLR <- SGSN: Cancel Location Error
1523 */
1524
1525 var BSSGP_ConnHdlr vc_conn;
1526 f_init();
1527 f_sleep(1.0);
1528 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1529 vc_conn.done;
1530}
1531
1532private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001533 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001534}
1535
1536testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1537 /* HLR -> SGSN: Cancel Location Request
1538 * HLR <- SGSN: Cancel Location Error
1539 */
1540
1541 var BSSGP_ConnHdlr vc_conn;
1542 f_init();
1543 f_sleep(1.0);
1544 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1545 vc_conn.done;
1546}
1547
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001548private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1549 f_TC_attach(id);
1550 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1551}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001552
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001553testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1554 /* MS <-> SGSN: Attach
1555 * MS -> SGSN: Detach Req (Power off)
1556 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1557 */
1558 var BSSGP_ConnHdlr vc_conn;
1559 var integer id := 33;
1560 var charstring imsi := hex2str(f_gen_imsi(id));
1561
1562 f_init();
1563 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb[0], id);
1564 vc_conn.done;
1565
1566 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1567}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001568
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001569/* Attempt an attach, but loose the Identification Request (IMEI) */
1570private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1571 var integer count_req := 0;
1572 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1573
1574 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1575
1576 alt {
1577 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1578 /* break */
1579 }
1580 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1581 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1582 BSSGP.send(ts_GMM_ID_RESP(mi));
1583 repeat;
1584 }
1585 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1586 /* ignore ID REQ IMEI */
1587 count_req := count_req + 1;
1588 repeat;
1589 }
1590 }
1591 if (count_req != 5) {
1592 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001593 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001594 }
1595 setverdict(pass);
1596}
1597
1598testcase TC_attach_no_imei_response() runs on test_CT {
1599 /* MS -> SGSN: Attach Request IMSI
1600 * MS <- SGSN: Identity Request IMSI (optional)
1601 * MS -> SGSN: Identity Response IMSI (optional)
1602 * MS <- SGSN: Identity Request IMEI
1603 * MS -x SGSN: no response
1604 * MS <- SGSN: re-send: Identity Request IMEI 4x
1605 * MS <- SGSN: Attach Reject
1606 */
1607 var BSSGP_ConnHdlr vc_conn;
1608 f_init();
1609 f_sleep(1.0);
1610 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1611 vc_conn.done;
1612}
1613
Alexander Couzens53f20562018-06-12 16:24:12 +02001614/* Attempt an attach, but loose the Identification Request (IMSI) */
1615private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1616 var integer count_req := 0;
1617 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1618
1619 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1620 g_pars.p_tmsi := 'c0000035'O;
1621
1622 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1623
1624 alt {
1625 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1626 /* break */
1627 }
1628 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1629 /* ignore ID REQ IMSI */
1630 count_req := count_req + 1;
1631 repeat;
1632 }
1633 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1634 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1635 BSSGP.send(ts_GMM_ID_RESP(mi));
1636 repeat;
1637 }
1638 }
1639 if (count_req != 5) {
1640 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001641 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001642 }
1643 setverdict(pass);
1644}
1645
1646testcase TC_attach_no_imsi_response() runs on test_CT {
1647 /* MS -> SGSN: Attach Request TMSI (unknown)
1648 * MS <- SGSN: Identity Request IMEI (optional)
1649 * MS -> SGSN: Identity Response IMEI (optional)
1650 * MS <- SGSN: Identity Request IMSI
1651 * MS -x SGSN: no response
1652 * MS <- SGSN: re-send: Identity Request IMSI 4x
1653 * MS <- SGSN: Attach Reject
1654 */
1655 var BSSGP_ConnHdlr vc_conn;
1656 f_init();
1657 f_sleep(1.0);
1658 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1659 vc_conn.done;
1660}
1661
Alexander Couzenscf818962018-06-05 18:00:00 +02001662private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1663 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1664}
1665
1666testcase TC_attach_check_subscriber_list() runs on test_CT {
1667 /* MS <-> SGSN: Attach
1668 * VTY -> SGSN: Check if MS is in subscriber cache
1669 */
1670 var BSSGP_ConnHdlr vc_conn;
1671 var integer id := 34;
1672 var charstring imsi := hex2str(f_gen_imsi(id));
1673
1674 f_init();
1675 f_sleep(1.0);
1676 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], id);
1677 vc_conn.done;
1678
1679 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1680 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1681}
1682
Alexander Couzensf9858652018-06-07 16:14:53 +02001683private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1684 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1685 var BssgpDecoded bd;
1686
1687 /* unregister the old IMSI */
1688 f_bssgp_client_unregister(g_pars.imsi);
1689 /* Simulate a foreign IMSI */
1690 g_pars.imsi := '001010123456789'H;
1691 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
1692
1693 /* there is no auth */
1694 g_pars.net.expect_auth := false;
1695
1696 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
1697 f_gmm_auth();
1698 alt {
1699 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1700 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001701 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001702 }
1703 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
1704 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1705 BSSGP.send(ts_GMM_ATTACH_COMPL);
1706 setverdict(pass);
1707 }
1708 }
1709}
1710testcase TC_attach_closed_add_vty() runs on test_CT {
1711 /* VTY-> SGSN: policy close
1712 * MS -> SGSN: Attach Request
1713 * MS <- SGSN: Identity Request IMSI
1714 * MS -> SGSN: Identity Response IMSI
1715 * MS <- SGSN: Attach Reject
1716 * VTY-> SGSN: policy imsi-acl add IMSI
1717 * MS -> SGSN: Attach Request
1718 * MS <- SGSN: Identity Request IMSI
1719 * MS -> SGSN: Identity Response IMSI
1720 * MS <- SGSN: Identity Request IMEI
1721 * MS -> SGSN: Identity Response IMEI
1722 * MS <- SGSN: Attach Accept
1723 */
1724 var BSSGP_ConnHdlr vc_conn;
1725 f_init();
1726 f_sleep(1.0);
1727 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1728 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
1729 /* test with foreign IMSI: Must Reject */
1730 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
1731 vc_conn.done;
1732 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456789");
1733 /* test with same IMSI: Must Accept */
1734 vc_conn := f_start_handler(refers(f_TC_attach_closed_imsi_added), testcasename(), g_gb[0], 10);
1735 vc_conn.done;
1736}
1737
Alexander Couzens0085bd72018-06-12 19:08:44 +02001738/* Attempt an attach, but never answer a Attach Complete */
1739private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1740 var integer count_req := 0;
1741
1742 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1743 f_gmm_auth();
1744
1745 alt {
1746 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1747 /* break */
1748 }
1749 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
1750 /* ignore */
1751 count_req := count_req + 1;
1752 repeat;
1753 }
1754 }
1755 if (count_req != 5) {
1756 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001757 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001758 }
1759 setverdict(pass);
1760}
1761
1762testcase TC_attach_check_complete_resend() runs on test_CT {
1763 /* MS -> SGSN: Attach Request IMSI
1764 * MS <- SGSN: Identity Request *
1765 * MS -> SGSN: Identity Response *
1766 * MS <- SGSN: Attach Complete 5x
1767 */
1768 var BSSGP_ConnHdlr vc_conn;
1769 f_init();
1770 f_sleep(1.0);
1771 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb[0], 36, 60.0);
1772 vc_conn.done;
1773}
1774
Harald Welte5ac31492018-02-15 20:39:13 +01001775control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001776 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001777 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001778 execute( TC_attach_umts_aka_umts_res() );
1779 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001780 execute( TC_attach_auth_id_timeout() );
1781 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001782 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001783 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001784 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001785 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001786 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001787 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001788 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001789 execute( TC_attach_no_imsi_response() );
Alexander Couzensf9858652018-06-07 16:14:53 +02001790 execute( TC_attach_closed_add_vty(), 10.0 );
Alexander Couzenscf818962018-06-05 18:00:00 +02001791 execute( TC_attach_check_subscriber_list(), 10.0 );
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001792 execute( TC_attach_detach_check_subscriber_list(), 10.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02001793 execute( TC_attach_check_complete_resend() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001794 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001795 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1796 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1797 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001798 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001799 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001800 execute( TC_detach_unknown_nopoweroff() );
1801 execute( TC_detach_unknown_poweroff() );
1802 execute( TC_detach_nopoweroff() );
1803 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001804 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001805 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001806 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001807 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001808 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001809 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001810 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001811 execute( TC_attach_restart_ctr_echo() );
1812 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001813 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001814 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Harald Welte5ac31492018-02-15 20:39:13 +01001815}
Harald Welte96a33b02018-02-04 10:36:22 +01001816
1817
1818
1819}