blob: 017c7243d4750f8bda276d6fe6b0b81e605e64a8 [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;
67};
68
Harald Welteeded9ad2018-02-17 20:57:34 +010069type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +010070 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +010071 timer g_Tguard;
Harald Welte5ac31492018-02-15 20:39:13 +010072}
73
74type record SGSN_ConnHdlrNetworkPars {
75 boolean expect_ptmsi,
76 boolean expect_auth,
77 boolean expect_ciph
78};
79
80type record BSSGP_ConnHdlrPars {
81 /* IMEI of the simulated ME */
82 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +020083 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +010084 hexstring imsi,
85 /* MSISDN of the simulated MS (probably unused) */
86 hexstring msisdn,
87 /* P-TMSI allocated to the simulated MS */
88 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +010089 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +010090 /* TLLI of the simulated MS */
91 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +010092 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +010093 RoutingAreaIdentificationV ra optional,
94 BssgpCellId bssgp_cell_id,
95 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +010096 SGSN_ConnHdlrNetworkPars net,
97 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +010098};
99
Harald Welte3fdbe822018-02-18 19:10:18 +0100100private function f_init_gb(inout GbInstance gb, charstring id) runs on test_CT {
101 gb.vc_NS := NS_CT.create(id & "-NS");
102 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP");
Harald Welte5ac31492018-02-15 20:39:13 +0100103 /* connect lower end of BSSGP emulation with NS upper port */
104 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
105 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
106 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
107
108 gb.vc_NS.start(NSStart());
109 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
110}
111
112private function f_init_gsup(charstring id) runs on test_CT {
113 id := id & "-GSUP";
114 var GsupOps ops := {
115 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
116 };
117
118 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
119 vc_GSUP := GSUP_Emulation_CT.create(id);
120
121 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
122 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
123 /* we use this hack to get events like ASP_IPA_EVENT_UP */
124 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
125
126 vc_GSUP.start(GSUP_Emulation.main(ops, id));
127 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
128
129 /* wait for incoming connection to GSUP port before proceeding */
130 timer T := 10.0;
131 T.start;
132 alt {
133 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
134 [] T.timeout {
135 setverdict(fail, "No connection to GSUP Port");
136 self.stop;
137 }
138 }
139}
140
Harald Welteeded9ad2018-02-17 20:57:34 +0100141private function f_init_gtp(charstring id) runs on test_CT {
142 id := id & "-GTP";
143
144 var GtpEmulationCfg gtp_cfg := {
145 gtpc_bind_ip := mp_ggsn_ip,
146 gtpc_bind_port := GTP1C_PORT,
147 gtpu_bind_ip := mp_ggsn_ip,
148 gtpu_bind_port := GTP1U_PORT,
149 sgsn_role := false
150 };
151
152 vc_GTP := GTP_Emulation_CT.create(id);
153 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
154}
155
Harald Weltebd194722018-02-16 22:11:08 +0100156private function f_init_vty() runs on test_CT {
157 map(self:SGSNVTY, system:SGSNVTY);
158 f_vty_set_prompts(SGSNVTY);
159 f_vty_transceive(SGSNVTY, "enable");
160 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
161}
162
163
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100164function f_init(BcdMccMnc mcc_mnc := '26242F'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100165 if (g_initialized == true) {
166 return;
167 }
168 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100169 g_gb[0].cfg := {
170 nsei := 96,
171 bvci := 196,
172 cell_id := {
173 ra_id := {
174 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100175 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100176 rac := 0
177 },
178 cell_id := 20960
179 },
180 sgsn_role := false
181 };
Harald Welte96a33b02018-02-04 10:36:22 +0100182
Harald Welte3fdbe822018-02-18 19:10:18 +0100183 f_init_gb(g_gb[0], "SGSN_Test-Gb0");
Harald Welte5ac31492018-02-15 20:39:13 +0100184 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100185 f_init_gtp("SGSN_Test");
Harald Weltebd194722018-02-16 22:11:08 +0100186 f_init_vty();
Harald Welte5ac31492018-02-15 20:39:13 +0100187}
Harald Welte96a33b02018-02-04 10:36:22 +0100188
Harald Welte5ac31492018-02-15 20:39:13 +0100189type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
190
191/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte62e29582018-02-16 21:17:11 +0100192function f_start_handler(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix,
193 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100194runs on test_CT return BSSGP_ConnHdlr {
195 var BSSGP_ConnHdlr vc_conn;
196 var SGSN_ConnHdlrNetworkPars net_pars := {
197 expect_ptmsi := true,
198 expect_auth := true,
199 expect_ciph := false
200 };
201 var BSSGP_ConnHdlrPars pars := {
202 imei := f_gen_imei(imsi_suffix),
203 imsi := f_gen_imsi(imsi_suffix),
204 msisdn := f_gen_msisdn(imsi_suffix),
205 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100206 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100207 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100208 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100209 ra := omit,
210 bssgp_cell_id := gb.cfg.cell_id,
211 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100212 net := net_pars,
213 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100214 };
215
216 vc_conn := BSSGP_ConnHdlr.create(id);
217 connect(vc_conn:BSSGP, gb.vc_BSSGP:BSSGP_SP);
218 connect(vc_conn:BSSGP_PROC, gb.vc_BSSGP:BSSGP_PROC);
219
220 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
221 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
222
Harald Welteeded9ad2018-02-17 20:57:34 +0100223 connect(vc_conn:GTP, vc_GTP:CLIENT);
224 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
225
Harald Welte5ac31492018-02-15 20:39:13 +0100226 vc_conn.start(f_handler_init(fn, id, pars));
227 return vc_conn;
228}
229
Harald Welte62e29582018-02-16 21:17:11 +0100230private altstep as_Tguard() runs on BSSGP_ConnHdlr {
231 [] g_Tguard.timeout {
232 setverdict(fail, "Tguard timeout");
233 self.stop;
234 }
235}
236
Harald Welte5ac31492018-02-15 20:39:13 +0100237/* first function called in every ConnHdlr */
238private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
239runs on BSSGP_ConnHdlr {
240 /* do some common stuff like setting up g_pars */
241 g_pars := pars;
242
243 /* register with BSSGP core */
244 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
245 /* tell GSUP dispatcher to send this IMSI to us */
246 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100247 /* tell GTP dispatcher to send this IMSI to us */
248 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100249
Harald Welte62e29582018-02-16 21:17:11 +0100250 g_Tguard.start(pars.t_guard);
251 activate(as_Tguard());
252
Harald Welte5ac31492018-02-15 20:39:13 +0100253 /* call the user-supplied test case function */
254 fn.apply(id);
255 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100256}
257
258/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100259 * Detach without Attach
260 * SM procedures without attach / RAU
261 * ATTACH / RAU
262 ** with / without authentication
263 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100264 * re-transmissions of LLC frames
265 * PDP Context activation
266 ** with different GGSN config in SGSN VTY
267 ** with different PDP context type (v4/v6/v46)
268 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100269 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100270 */
271
272testcase TC_wait_ns_up() runs on test_CT {
273 f_init();
274 f_sleep(20.0);
275}
276
Harald Welte5ac31492018-02-15 20:39:13 +0100277altstep as_mm_identity() runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100278 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welte5ac31492018-02-15 20:39:13 +0100279 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
280 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
281 BSSGP.send(ts_GMM_ID_RESP(mi));
282 repeat;
283 }
284 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
285 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
286 BSSGP.send(ts_GMM_ID_RESP(mi));
287 repeat;
288 }
289}
Harald Welte96a33b02018-02-04 10:36:22 +0100290
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200291/* perform GMM authentication (if expected).
292 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
293 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
294function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100295 var BssgpDecoded bd;
296 var PDU_L3_MS_SGSN l3_mo;
297 var PDU_L3_SGSN_MS l3_mt;
298 var default di := activate(as_mm_identity());
299 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200300 var GSUP_IE auth_tuple;
301 var template AuthenticationParameterAUTNTLV autn;
302
303 if (umts_aka_challenge) {
304 g_pars.vec := f_gen_auth_vec_3g();
305 autn := {
306 elementIdentifier := '28'O,
307 lengthIndicator := lengthof(g_pars.vec.autn),
308 autnValue := g_pars.vec.autn
309 };
310
311 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
312 g_pars.vec.sres,
313 g_pars.vec.kc,
314 g_pars.vec.ik,
315 g_pars.vec.ck,
316 g_pars.vec.autn,
317 g_pars.vec.res));
318 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
319 } else {
320 g_pars.vec := f_gen_auth_vec_2g();
321 autn := omit;
322 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
323 g_pars.vec.sres,
324 g_pars.vec.kc));
325 log("GSUP sends only 2G auth tuple", auth_tuple);
326 }
Harald Welte5ac31492018-02-15 20:39:13 +0100327 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
328 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200329
330 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
331 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
332 BSSGP.receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
Harald Welte5ac31492018-02-15 20:39:13 +0100333 l3_mt := bd.l3_mt;
334 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200335 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
336
337 if (umts_aka_challenge and not force_gsm_sres) {
338 /* set UMTS response instead */
339 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
340 valueField := substr(g_pars.vec.res, 0, 4)
341 };
342 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
343 elementIdentifier := '21'O,
344 lengthIndicator := lengthof(g_pars.vec.res) - 4,
345 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
346 };
347 }
348
349 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100350 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
351 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
352 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
353 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
354 }
355 BSSGP.send(l3_mo);
Harald Welte76dee092018-02-16 22:12:59 +0100356 } else {
357 /* wait for identity procedure */
358 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100359 }
Harald Welte76dee092018-02-16 22:12:59 +0100360
Harald Welte5ac31492018-02-15 20:39:13 +0100361 deactivate(di);
362}
363
Harald Weltef70997d2018-02-17 10:11:19 +0100364function f_upd_ptmsi_and_tlli(OCT4 p_tmsi) runs on BSSGP_ConnHdlr {
365 g_pars.p_tmsi := p_tmsi;
366 /* update TLLI */
367 g_pars.tlli_old := g_pars.tlli;
368 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
369 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli);
370}
371
Harald Welte04683d02018-02-16 22:43:45 +0100372function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
373 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100374 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
375 if (not (g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc == aa_plmn)) {
376 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
377 & "; expected " & hex2str(g_pars.bssgp_cell_id.ra_id.lai.mcc_mnc));
378 self.stop;
379 }
Harald Welte04683d02018-02-16 22:43:45 +0100380 g_pars.ra := aa.routingAreaIdentification;
381 if (ispresent(aa.allocatedPTMSI)) {
382 if (not g_pars.net.expect_ptmsi) {
383 setverdict(fail, "unexpected P-TMSI allocation");
384 self.stop;
385 }
Harald Weltef70997d2018-02-17 10:11:19 +0100386 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100387 }
388 if (ispresent(aa.msIdentity)) {
389 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
390 self.stop;
391 }
392 /* P-TMSI.sig */
393 if (ispresent(aa.ptmsiSignature)) {
394 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
395 }
396 /* updateTimer */
397 // aa.readyTimer
398 /* T3302, T3319, T3323, T3312_ext, T3324 */
399}
400
Harald Welte91636de2018-02-17 10:16:14 +0100401function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra) runs on BSSGP_ConnHdlr {
402 /* mandatory IE */
403 g_pars.ra := ra.routingAreaId;
404 if (ispresent(ra.allocatedPTMSI)) {
405 if (not g_pars.net.expect_ptmsi) {
406 setverdict(fail, "unexpected P-TMSI allocation");
407 self.stop;
408 }
409 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
410 }
411 if (ispresent(ra.msIdentity)) {
412 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
413 self.stop;
414 }
415 /* P-TMSI.sig */
416 if (ispresent(ra.ptmsiSignature)) {
417 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
418 }
419 /* updateTimer */
420 // aa.readyTimer
421 /* T3302, T3319, T3323, T3312_ext, T3324 */
422}
423
424
Harald Welte5a4fa042018-02-16 20:59:21 +0100425function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
426 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
427}
428
Harald Welte23178c52018-02-17 09:36:33 +0100429/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100430private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100431 if (ispresent(g_pars.p_tmsi)) {
432 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
433 } else {
434 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
435 }
436}
437
Harald Welte311ec272018-02-17 09:40:03 +0100438private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100439 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100440 /* Expect MSC to perform LU with HLR */
441 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100442 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
443 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
444 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100445 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
446 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
447}
448
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200449private function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100450 var BssgpDecoded bd;
Harald Welte5a4fa042018-02-16 20:59:21 +0100451 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200452 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 +0100453
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200454 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
455 * 3G auth vectors */
456 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
457 /* The thing is, if the solSACapability is 'omit', then the
458 * revisionLevelIndicatior is at the wrong place! */
459 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
460
461 BSSGP.send(attach_req);
462 f_gmm_auth(umts_aka_challenge, force_gsm_sres);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200463 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100464 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100465
Harald Welte04683d02018-02-16 22:43:45 +0100466 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
467 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
468 }
469 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welte5ac31492018-02-15 20:39:13 +0100470 BSSGP.send(ts_GMM_ATTACH_COMPL);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200471}
472
473private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
474 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100475 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100476}
477
478testcase TC_attach() runs on test_CT {
479 var BSSGP_ConnHdlr vc_conn;
480 f_init();
481 f_sleep(1.0);
482 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1);
483 vc_conn.done;
484}
485
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100486testcase TC_attach_mnc3() runs on test_CT {
487 var BSSGP_ConnHdlr vc_conn;
488 f_init('023042'H);
489 f_sleep(1.0);
490 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1001);
491 vc_conn.done;
492}
493
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200494private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
495 f_gmm_attach(true, false);
496 setverdict(pass);
497}
498testcase TC_attach_umts_aka_umts_res() runs on test_CT {
499 var BSSGP_ConnHdlr vc_conn;
500 f_init();
501 f_sleep(1.0);
502 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb[0], 1002);
503 vc_conn.done;
504}
505
506private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
507 f_gmm_attach(true, true);
508 setverdict(pass);
509}
510testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
511 var BSSGP_ConnHdlr vc_conn;
512 f_init();
513 f_sleep(1.0);
514 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb[0], 1003);
515 vc_conn.done;
516}
517
Harald Welte5b7c8122018-02-16 21:48:17 +0100518/* MS never responds to ID REQ, expect ATTACH REJECT */
519private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100520 var RoutingAreaIdentificationV old_ra := f_random_RAI();
521
Harald Welte23178c52018-02-17 09:36:33 +0100522 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100523 alt {
Harald Welte1967d472018-02-16 21:54:21 +0100524 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100525 /* don't send ID Response */
526 repeat;
527 }
Harald Welte1967d472018-02-16 21:54:21 +0100528 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100529 setverdict(pass);
530 }
Harald Welte1967d472018-02-16 21:54:21 +0100531 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100532 setverdict(fail, "Wrong Attach Reject Cause");
533 }
534 }
535}
536testcase TC_attach_auth_id_timeout() runs on test_CT {
537 var BSSGP_ConnHdlr vc_conn;
538 f_init();
539 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb[0], 2, 40.0);
540 vc_conn.done;
541}
542
543/* HLR never responds to SAI REQ, expect ATTACH REJECT */
544private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100545 var RoutingAreaIdentificationV old_ra := f_random_RAI();
546
Harald Welte23178c52018-02-17 09:36:33 +0100547 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100548 alt {
549 [] as_mm_identity();
550 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
551 }
552 /* don't send SAI-response from HLR */
Harald Welte1967d472018-02-16 21:54:21 +0100553 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100554 setverdict(pass);
555}
556testcase TC_attach_auth_sai_timeout() runs on test_CT {
557 var BSSGP_ConnHdlr vc_conn;
558 f_init();
559 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb[0], 3);
560 vc_conn.done;
561}
562
Harald Weltefe253882018-02-17 09:25:00 +0100563/* HLR rejects SAI, expect ATTACH REJECT */
564private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100565 var RoutingAreaIdentificationV old_ra := f_random_RAI();
566
Harald Welte23178c52018-02-17 09:36:33 +0100567 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100568 alt {
569 [] as_mm_identity();
570 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
571 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
572 }
573 }
574 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
575 setverdict(pass);
576}
577testcase TC_attach_auth_sai_reject() runs on test_CT {
578 var BSSGP_ConnHdlr vc_conn;
579 f_init();
Harald Welteb7c14e92018-02-17 09:29:16 +0100580 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb[0], 4);
Harald Weltefe253882018-02-17 09:25:00 +0100581 vc_conn.done;
582}
583
Harald Welte5b7c8122018-02-16 21:48:17 +0100584/* HLR never responds to UL REQ, expect ATTACH REJECT */
585private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100586 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100587 var RoutingAreaIdentificationV old_ra := f_random_RAI();
588
Harald Welte23178c52018-02-17 09:36:33 +0100589 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100590 f_gmm_auth();
591 /* Expect MSC to perform LU with HLR */
592 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
593 /* Never follow-up with ISD_REQ or UL_RES */
594 alt {
Harald Welte1967d472018-02-16 21:54:21 +0100595 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100596 setverdict(pass);
597 }
Harald Welte04683d02018-02-16 22:43:45 +0100598 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
599 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100600 setverdict(fail);
601 }
602 }
603}
604testcase TC_attach_gsup_lu_timeout() runs on test_CT {
605 var BSSGP_ConnHdlr vc_conn;
606 f_init();
607 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100608 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb[0], 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100609 vc_conn.done;
610}
611
Harald Welteb7c14e92018-02-17 09:29:16 +0100612/* HLR rejects UL REQ, expect ATTACH REJECT */
613private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
614 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100615 var RoutingAreaIdentificationV old_ra := f_random_RAI();
616
Harald Welte23178c52018-02-17 09:36:33 +0100617 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100618 f_gmm_auth();
619 /* Expect MSC to perform LU with HLR */
620 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
621 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
622 }
623 alt {
624 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
625 setverdict(pass);
626 }
627 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
628 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
629 setverdict(fail);
630 }
631 }
632}
633testcase TC_attach_gsup_lu_reject() runs on test_CT {
634 var BSSGP_ConnHdlr vc_conn;
635 f_init();
636 f_sleep(1.0);
637 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb[0], 6);
638 vc_conn.done;
639}
640
641
Harald Welte3823e2e2018-02-16 21:53:48 +0100642/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
643private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100644 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100645 var RoutingAreaIdentificationV old_ra := f_random_RAI();
646
Harald Welte23178c52018-02-17 09:36:33 +0100647 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100648 f_gmm_auth();
649 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100650 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100651
Harald Welte04683d02018-02-16 22:43:45 +0100652 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
653 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
654 }
Harald Welte3823e2e2018-02-16 21:53:48 +0100655 BSSGP.send(ts_GMM_ATTACH_COMPL);
656 setverdict(pass);
657}
Harald Welte3823e2e2018-02-16 21:53:48 +0100658testcase TC_attach_combined() runs on test_CT {
659 var BSSGP_ConnHdlr vc_conn;
660 f_init();
661 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100662 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb[0], 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100663 vc_conn.done;
664}
665
Harald Welte76dee092018-02-16 22:12:59 +0100666/* Attempt of GPRS ATTACH in 'accept all' mode */
667private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100668 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100669 var RoutingAreaIdentificationV old_ra := f_random_RAI();
670
671 g_pars.net.expect_auth := false;
672
Harald Welte23178c52018-02-17 09:36:33 +0100673 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100674 f_gmm_auth();
Harald Welte04683d02018-02-16 22:43:45 +0100675 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
676 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
677 }
Harald Welte76dee092018-02-16 22:12:59 +0100678 BSSGP.send(ts_GMM_ATTACH_COMPL);
679 setverdict(pass);
680}
681testcase TC_attach_accept_all() runs on test_CT {
682 var BSSGP_ConnHdlr vc_conn;
683 f_init();
684 f_sleep(1.0);
685 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Harald Welteb7c14e92018-02-17 09:29:16 +0100686 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 8);
Harald Welte76dee092018-02-16 22:12:59 +0100687 vc_conn.done;
688}
Harald Welte5b7c8122018-02-16 21:48:17 +0100689
Harald Welteb2124b22018-02-16 22:26:56 +0100690/* Attempt of GPRS ATTACH in 'accept all' mode */
691private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100692 var RoutingAreaIdentificationV old_ra := f_random_RAI();
693
694 /* Simulate a foreign IMSI */
695 g_pars.imsi := '001010123456789'H;
696 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
697
698 g_pars.net.expect_auth := false;
699
Harald Welte23178c52018-02-17 09:36:33 +0100700 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100701 alt {
702 [] as_mm_identity();
703 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
704 setverdict(pass);
705 }
706 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
707 setverdict(pass);
708 }
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200709 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
710 setverdict(fail);
711 }
Harald Welteb2124b22018-02-16 22:26:56 +0100712 }
713}
714testcase TC_attach_closed() runs on test_CT {
715 var BSSGP_ConnHdlr vc_conn;
716 f_init();
717 f_sleep(1.0);
718 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
719 /* test with foreign IMSI: Must Reject */
Harald Welteb7c14e92018-02-17 09:29:16 +0100720 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100721 vc_conn.done;
722 /* test with home IMSI: Must Accept */
Harald Welteb7c14e92018-02-17 09:29:16 +0100723 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100724 vc_conn.done;
725}
726
Harald Welte04683d02018-02-16 22:43:45 +0100727/* Routing Area Update from Unknown TLLI -> REJECT */
728private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100729 var RoutingAreaIdentificationV old_ra := f_random_RAI();
730
Harald Welte23178c52018-02-17 09:36:33 +0100731 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 +0100732 alt {
733 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
734 setverdict(pass);
735 }
736 /* FIXME: Expect XID RESET? */
737 [] BSSGP.receive { repeat; }
738 }
739}
740testcase TC_rau_unknown() runs on test_CT {
741 var BSSGP_ConnHdlr vc_conn;
742 f_init();
743 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100744 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb[0], 11);
Harald Welte04683d02018-02-16 22:43:45 +0100745 vc_conn.done;
746}
747
Harald Welte91636de2018-02-17 10:16:14 +0100748private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
749 var BssgpDecoded bd;
750
751 /* first perform regular attach */
752 f_TC_attach(id);
753
754 /* then send RAU */
755 BSSGP.send(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit));
756 alt {
757 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
758 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept);
Alexander Couzens80ec1ea2018-05-12 16:44:36 +0200759 BSSGP.send(ts_GMM_RAU_COMPL);
Harald Welte91636de2018-02-17 10:16:14 +0100760 setverdict(pass);
761 }
762 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
763 setverdict(fail, "Unexpected RAU Reject");
764 }
765 [] BSSGP.receive { repeat; }
766 }
767}
768testcase TC_attach_rau() runs on test_CT {
769 var BSSGP_ConnHdlr vc_conn;
770 f_init();
771 f_sleep(1.0);
772 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb[0], 12);
773 vc_conn.done;
774}
Harald Welte04683d02018-02-16 22:43:45 +0100775
Harald Welte6abb9fe2018-02-17 15:24:48 +0100776/* general GPRS DETACH helper */
777function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge) runs on BSSGP_ConnHdlr {
778 var BssgpDecoded bd;
779 timer T := 5.0;
780 BSSGP.send(ts_GMM_DET_REQ_MO(detach_type, power_off));
781 if (expect_purge) {
782 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
783 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
784 }
785 T.start;
786 alt {
787 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
788 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
789 }
790 [power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
791 g_pars.ra := omit;
792 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
793 /* TODO: check if any PDP contexts are deactivated on network side? */
794 }
795 [power_off] T.timeout {
796 setverdict(pass);
797 }
798 [not power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
799 g_pars.ra := omit;
800 setverdict(pass);
801 /* TODO: check if any PDP contexts are deactivated on network side? */
802 }
803 [] BSSGP.receive { repeat; }
804 }
805}
806
807/* IMSI DETACH (non-power-off) for unknown TLLI */
808private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
809 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
810}
811testcase TC_detach_unknown_nopoweroff() runs on test_CT {
812 var BSSGP_ConnHdlr vc_conn;
813 f_init();
814 f_sleep(1.0);
815 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb[0], 13);
816 vc_conn.done;
817}
818
819/* IMSI DETACH (power-off) for unknown TLLI */
820private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
821 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
822}
823testcase TC_detach_unknown_poweroff() runs on test_CT {
824 var BSSGP_ConnHdlr vc_conn;
825 f_init();
826 f_sleep(1.0);
827 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb[0], 14);
828 vc_conn.done;
829}
830
831/* IMSI DETACH (non-power-off) for known TLLI */
832private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
833 /* first perform regular attach */
834 f_TC_attach(id);
835
836 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
837}
838testcase TC_detach_nopoweroff() runs on test_CT {
839 var BSSGP_ConnHdlr vc_conn;
840 f_init();
841 f_sleep(1.0);
842 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb[0], 15);
843 vc_conn.done;
844}
845
846/* IMSI DETACH (power-off) for known TLLI */
847private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
848 /* first perform regular attach */
849 f_TC_attach(id);
850
851 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
852}
853testcase TC_detach_poweroff() runs on test_CT {
854 var BSSGP_ConnHdlr vc_conn;
855 f_init();
856 f_sleep(1.0);
857 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb[0], 16);
858 vc_conn.done;
859}
860
Harald Welteeded9ad2018-02-17 20:57:34 +0100861type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100862 BIT3 tid, /* L3 Transaction ID */
863 BIT4 nsapi, /* SNDCP NSAPI */
864 BIT4 sapi, /* LLC SAPI */
865 QoSV qos, /* QoS parameters */
866 PDPAddressV addr, /* IP address */
867 octetstring apn optional, /* APN name */
868 ProtocolConfigOptionsV pco optional, /* protoco config opts */
869 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100870 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100871 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100872
Harald Welte822f9102018-02-18 20:39:06 +0100873 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
874 OCT4 ggsn_tei_u, /* GGSN TEI User */
875 octetstring ggsn_ip_c, /* GGSN IP Control */
876 octetstring ggsn_ip_u, /* GGSN IP User */
Harald Welteeded9ad2018-02-17 20:57:34 +0100877
Harald Welte822f9102018-02-18 20:39:06 +0100878 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
879 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
880 octetstring sgsn_ip_c optional, /* SGSN IP Control */
881 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100882};
883
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100884
885private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
886 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
887 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
888 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
889 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
890 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
891 f_gtp_register_teid(apars.ggsn_tei_c);
892 f_gtp_register_teid(apars.ggsn_tei_u);
893}
894
Harald Welte37692d82018-02-18 15:21:34 +0100895function f_pdp_ctx_act(inout PdpActPars apars) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100896 var boolean exp_rej := ispresent(apars.exp_rej_cause);
897 var Gtp1cUnitdata g_ud;
898
899 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
900 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100901 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
902 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
903 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
904 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
905 apars.sgsn_tei_c, apars.gtp_resp_cause,
906 apars.ggsn_tei_c, apars.ggsn_tei_u,
907 apars.nsapi,
908 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id));
Harald Welteeded9ad2018-02-17 20:57:34 +0100909 }
910 alt {
Harald Welte28307082018-02-18 12:14:18 +0100911 [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 +0100912 setverdict(pass);
913 }
Harald Welte28307082018-02-18 12:14:18 +0100914 [exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100915 setverdict(fail, "Unexpected PDP CTX ACT ACC");
916 }
Harald Welte28307082018-02-18 12:14:18 +0100917 [not exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100918 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
919 }
Harald Welte28307082018-02-18 12:14:18 +0100920 [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 +0100921 setverdict(pass);
922 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100923 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +0100924 }
925}
926
Harald Welte6f203162018-02-18 22:04:55 +0100927function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
928 var boolean exp_rej := ispresent(apars.exp_rej_cause);
929 var Gtp1cUnitdata g_ud;
930
931 BSSGP.send(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
932 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
933 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
934 BSSGP.clear;
935 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
936 }
937 alt {
938 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
939 setverdict(pass);
940 }
941 [] as_xid(apars);
942 }
943}
944
Harald Welte57b9b7f2018-02-18 22:28:13 +0100945function f_pdp_ctx_deact_mt(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
946 var Gtp1cUnitdata g_ud;
947 var integer seq_nr := 23;
948 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
949
950 BSSGP.clear;
951 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, omit));
952
953 interleave {
954 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?))) {
955 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
956 }
957 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) { }
958 }
959}
960
Harald Welte6f203162018-02-18 22:04:55 +0100961
Harald Welteeded9ad2018-02-17 20:57:34 +0100962/* Table 10.5.156/3GPP TS 24.008 */
963template (value) QoSV t_QosDefault := {
964 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
965 delayClass := '100'B, /* best effort */
966 spare1 := '00'B,
967 precedenceClass := '010'B, /* normal */
968 spare2 := '0'B,
969 peakThroughput := '0000'B, /* subscribed */
970 meanThroughput := '00000'B, /* subscribed */
971 spare3 := '000'B,
972 deliverErroneusSDU := omit,
973 deliveryOrder := omit,
974 trafficClass := omit,
975 maxSDUSize := omit,
976 maxBitrateUplink := omit,
977 maxBitrateDownlink := omit,
978 sduErrorRatio := omit,
979 residualBER := omit,
980 trafficHandlingPriority := omit,
981 transferDelay := omit,
982 guaranteedBitRateUplink := omit,
983 guaranteedBitRateDownlink := omit,
984 sourceStatisticsDescriptor := omit,
985 signallingIndication := omit,
986 spare4 := omit,
987 maxBitrateDownlinkExt := omit,
988 guaranteedBitRateDownlinkExt := omit,
989 maxBitrateUplinkExt := omit,
990 guaranteedBitRateUplinkExt := omit,
991 maxBitrateDownlinkExt2 := omit,
992 guaranteedBitRateDownlinkExt2 := omit,
993 maxBitrateUplinkExt2 := omit,
994 guaranteedBitRateUplinkExt2 := omit
995}
996
997/* 10.5.6.4 / 3GPP TS 24.008 */
998template (value) PDPAddressV t_AddrIPv4dyn := {
999 pdpTypeOrg := '0001'B, /* IETF */
1000 spare := '0000'B,
1001 pdpTypeNum := '21'O, /* IPv4 */
1002 addressInfo := omit
1003}
1004template (value) PDPAddressV t_AddrIPv6dyn := {
1005 pdpTypeOrg := '0001'B, /* IETF */
1006 spare := '0000'B,
1007 pdpTypeNum := '53'O, /* IPv6 */
1008 addressInfo := omit
1009}
1010
Harald Welte37692d82018-02-18 15:21:34 +01001011template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001012 tid := '000'B,
1013 nsapi := '0101'B, /* < 5 are reserved */
1014 sapi := '0011'B, /* 3/5/9/11 */
1015 qos := t_QosDefault,
1016 addr := t_AddrIPv4dyn,
1017 apn := omit,
1018 pco := omit,
1019 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001020 gtp_resp_cause := int2oct(128, 1),
1021 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001022
1023 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001024 ggsn_tei_c := f_rnd_octstring(4),
1025 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001026 ggsn_ip_c := f_inet_addr(ggsn_ip),
1027 ggsn_ip_u := f_inet_addr(ggsn_ip),
Harald Welteeded9ad2018-02-17 20:57:34 +01001028
Harald Welteeded9ad2018-02-17 20:57:34 +01001029 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001030 sgsn_tei_u := omit,
1031 sgsn_ip_c := omit,
1032 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001033}
1034
Harald Welte37692d82018-02-18 15:21:34 +01001035template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1036 connId := 1,
1037 remName := f_inet_ntoa(ip),
1038 remPort := GTP1U_PORT
1039}
1040
1041template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1042 connId := 1,
1043 remName := f_inet_ntoa(ip),
1044 remPort := GTP1C_PORT
1045}
1046
1047private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1048 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1049 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1050}
1051
1052private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
1053 [] BSSGP.receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
1054 repeat;
1055 }
1056}
1057
1058template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1059 pDU_SN_UNITDATA := {
1060 nsapi := nsapi,
1061 moreBit := ?,
1062 snPduType := '1'B,
1063 firstSegmentIndicator := ?,
1064 spareBit := ?,
1065 pcomp := ?,
1066 dcomp := ?,
1067 npduNumber := ?,
1068 segmentNumber := ?,
1069 npduNumberContinued := ?,
1070 dataSegmentSnUnitdataPdu := payload
1071 }
1072}
1073
1074/* simple case: single segment, no compression */
1075template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1076 pDU_SN_UNITDATA := {
1077 nsapi := nsapi,
1078 moreBit := '0'B,
1079 snPduType := '1'B,
1080 firstSegmentIndicator := '1'B,
1081 spareBit := '0'B,
1082 pcomp := '0000'B,
1083 dcomp := '0000'B,
1084 npduNumber := '0000'B,
1085 segmentNumber := '0000'B,
1086 npduNumberContinued := '00'O,
1087 dataSegmentSnUnitdataPdu := payload
1088 }
1089}
1090
1091/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1092private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1093 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1094 f_gtpu_send(apars, payload);
1095 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1096 alt {
1097 [] as_xid(apars);
1098 [] BSSGP.receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1099 }
1100}
1101
1102private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1103 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1104 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1105 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
1106 BSSGP.send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
1107 f_gtpu_send(apars, payload);
1108 /* Expect PDU via GTP from SGSN on simulated GGSN */
1109 alt {
1110 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1111 }
1112}
1113
Harald Welteeded9ad2018-02-17 20:57:34 +01001114private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001115 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001116
1117 /* first perform regular attach */
1118 f_TC_attach(id);
1119
1120 f_pdp_ctx_act(apars);
1121}
1122testcase TC_attach_pdp_act() runs on test_CT {
1123 var BSSGP_ConnHdlr vc_conn;
1124 f_init();
1125 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1126 vc_conn.done;
1127}
Harald Welteb2124b22018-02-16 22:26:56 +01001128
Harald Welte835b15f2018-02-18 14:39:11 +01001129/* PDP Context activation for not-attached subscriber; expect fail */
1130private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001131 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welte835b15f2018-02-18 14:39:11 +01001132 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1133 apars.apn, apars.pco));
1134 alt {
1135 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
1136 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
1137 setverdict(pass);
1138 }
1139 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1140 setverdict(fail, "Unexpected GTP PDP CTX ACT");
1141 }
1142 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
1143 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
1144 }
1145 [] BSSGP.receive { repeat; }
1146 }
1147}
1148testcase TC_pdp_act_unattached() runs on test_CT {
1149 var BSSGP_ConnHdlr vc_conn;
1150 f_init();
1151 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1152 vc_conn.done;
1153}
1154
Harald Welte37692d82018-02-18 15:21:34 +01001155/* ATTACH + PDP CTX ACT + user plane traffic */
1156private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1157 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1158
1159 /* first perform regular attach */
1160 f_TC_attach(id);
1161 /* then activate PDP context */
1162 f_pdp_ctx_act(apars);
1163 /* then transceive a downlink PDU */
1164 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1165 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1166}
1167testcase TC_attach_pdp_act_user() runs on test_CT {
1168 var BSSGP_ConnHdlr vc_conn;
1169 f_init();
1170 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1171 vc_conn.done;
1172}
1173
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001174/* ATTACH + PDP CTX ACT; reject from GGSN */
1175private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1176 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1177
1178 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1179 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1180
1181 /* first perform regular attach */
1182 f_TC_attach(id);
1183 /* then activate PDP context */
1184 f_pdp_ctx_act(apars);
1185}
1186testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1187 var BSSGP_ConnHdlr vc_conn;
1188 f_init();
1189 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1190 vc_conn.done;
1191}
Harald Welte835b15f2018-02-18 14:39:11 +01001192
Harald Welte6f203162018-02-18 22:04:55 +01001193/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1194private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1195 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1196
1197 /* first perform regular attach */
1198 f_TC_attach(id);
1199 /* then activate PDP context */
1200 f_pdp_ctx_act(apars);
1201 /* then transceive a downlink PDU */
1202 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1203 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1204
1205 f_pdp_ctx_deact_mo(apars, '00'O);
1206}
1207testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1208 var BSSGP_ConnHdlr vc_conn;
1209 f_init();
1210 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1211 vc_conn.done;
1212}
1213
Harald Welte57b9b7f2018-02-18 22:28:13 +01001214/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1215private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1216 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1217
1218 /* first perform regular attach */
1219 f_TC_attach(id);
1220 /* then activate PDP context */
1221 f_pdp_ctx_act(apars);
1222 /* then transceive a downlink PDU */
1223 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1224 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1225
1226 f_pdp_ctx_deact_mt(apars, '00'O);
1227}
1228testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1229 var BSSGP_ConnHdlr vc_conn;
1230 f_init();
1231 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1232 vc_conn.done;
1233}
1234
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001235/* ATTACH + ATTACH (2nd) */
1236private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1237 g_pars.t_guard := 5.0;
1238
1239 /* first perform regular attach */
1240 f_TC_attach(id);
1241
1242 /* second to perform regular attach */
1243 f_TC_attach(id);
1244}
1245
1246
1247testcase TC_attach_second_attempt() runs on test_CT {
1248 var BSSGP_ConnHdlr vc_conn;
1249 f_init();
1250 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1251 vc_conn.done;
1252}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001253
Alexander Couzens5e307b42018-05-22 18:12:20 +02001254private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1255 /* MS: perform regular attach */
1256 f_TC_attach(id);
1257
1258 /* HLR: cancel the location request */
1259 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1260 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001261
1262 /* ensure no Detach Request got received */
1263 timer T := 5.0;
1264 T.start;
1265 alt {
1266 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
1267 T.stop;
1268 setverdict(fail, "Unexpected GMM Detach Request");
1269 }
1270 [] T.timeout {
1271 setverdict(pass);
1272 self.stop;
1273 }
1274 [] BSSGP.receive {
1275 repeat;
1276 }
1277 }
1278}
1279
1280testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1281 /* MS <-> SGSN: GMM Attach
1282 * HLR -> SGSN: Cancel Location Request
1283 * HLR <- SGSN: Cancel Location Ack
1284 */
1285 var BSSGP_ConnHdlr vc_conn;
1286 f_init();
1287 f_sleep(1.0);
1288 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1289 vc_conn.done;
1290}
1291
1292
Alexander Couzensc87967a2018-05-22 16:09:54 +02001293private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1294 /* MS: perform regular attach */
1295 f_TC_attach(id);
1296
1297 /* HLR: cancel the location request */
1298 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1299 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1300 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1301
1302 /* MS: receive a Detach Request */
1303 BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1304 BSSGP.send(ts_GMM_DET_ACCEPT_MO);
1305
1306 setverdict(pass);
1307}
1308
1309testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1310 /* MS <-> SGSN: GMM Attach
1311 * HLR -> SGSN: Cancel Location Request
1312 * HLR <- SGSN: Cancel Location Ack
1313 * MS <- SGSN: Detach Request
1314 * SGSN-> MS: Detach Complete
1315 */
1316 var BSSGP_ConnHdlr vc_conn;
1317 f_init();
1318 f_sleep(1.0);
1319 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1320 vc_conn.done;
1321}
1322
1323
Alexander Couzens6c47f292018-05-22 17:09:49 +02001324private function f_hlr_location_cancel_request_unknown_subscriber(
1325 charstring id,
1326 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1327
1328 /* HLR: cancel the location request */
1329 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1330
1331 /* cause 2 = IMSI_UNKNOWN */
1332 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1333
1334 setverdict(pass);
1335}
1336
1337private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001338 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001339}
1340
1341testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1342 /* HLR -> SGSN: Cancel Location Request
1343 * HLR <- SGSN: Cancel Location Error
1344 */
1345
1346 var BSSGP_ConnHdlr vc_conn;
1347 f_init();
1348 f_sleep(1.0);
1349 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1350 vc_conn.done;
1351}
1352
1353private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001354 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001355}
1356
1357testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1358 /* HLR -> SGSN: Cancel Location Request
1359 * HLR <- SGSN: Cancel Location Error
1360 */
1361
1362 var BSSGP_ConnHdlr vc_conn;
1363 f_init();
1364 f_sleep(1.0);
1365 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1366 vc_conn.done;
1367}
1368
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001369private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1370 f_TC_attach(id);
1371 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1372}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001373
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001374testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1375 /* MS <-> SGSN: Attach
1376 * MS -> SGSN: Detach Req (Power off)
1377 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1378 */
1379 var BSSGP_ConnHdlr vc_conn;
1380 var integer id := 33;
1381 var charstring imsi := hex2str(f_gen_imsi(id));
1382
1383 f_init();
1384 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb[0], id);
1385 vc_conn.done;
1386
1387 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1388}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001389
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001390/* Attempt an attach, but loose the Identification Request (IMEI) */
1391private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1392 var integer count_req := 0;
1393 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1394
1395 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1396
1397 alt {
1398 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1399 /* break */
1400 }
1401 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1402 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1403 BSSGP.send(ts_GMM_ID_RESP(mi));
1404 repeat;
1405 }
1406 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1407 /* ignore ID REQ IMEI */
1408 count_req := count_req + 1;
1409 repeat;
1410 }
1411 }
1412 if (count_req != 5) {
1413 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
1414 }
1415 setverdict(pass);
1416}
1417
1418testcase TC_attach_no_imei_response() runs on test_CT {
1419 /* MS -> SGSN: Attach Request IMSI
1420 * MS <- SGSN: Identity Request IMSI (optional)
1421 * MS -> SGSN: Identity Response IMSI (optional)
1422 * MS <- SGSN: Identity Request IMEI
1423 * MS -x SGSN: no response
1424 * MS <- SGSN: re-send: Identity Request IMEI 4x
1425 * MS <- SGSN: Attach Reject
1426 */
1427 var BSSGP_ConnHdlr vc_conn;
1428 f_init();
1429 f_sleep(1.0);
1430 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1431 vc_conn.done;
1432}
1433
Alexander Couzens53f20562018-06-12 16:24:12 +02001434/* Attempt an attach, but loose the Identification Request (IMSI) */
1435private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1436 var integer count_req := 0;
1437 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1438
1439 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1440 g_pars.p_tmsi := 'c0000035'O;
1441
1442 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1443
1444 alt {
1445 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1446 /* break */
1447 }
1448 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1449 /* ignore ID REQ IMSI */
1450 count_req := count_req + 1;
1451 repeat;
1452 }
1453 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1454 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1455 BSSGP.send(ts_GMM_ID_RESP(mi));
1456 repeat;
1457 }
1458 }
1459 if (count_req != 5) {
1460 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
1461 }
1462 setverdict(pass);
1463}
1464
1465testcase TC_attach_no_imsi_response() runs on test_CT {
1466 /* MS -> SGSN: Attach Request TMSI (unknown)
1467 * MS <- SGSN: Identity Request IMEI (optional)
1468 * MS -> SGSN: Identity Response IMEI (optional)
1469 * MS <- SGSN: Identity Request IMSI
1470 * MS -x SGSN: no response
1471 * MS <- SGSN: re-send: Identity Request IMSI 4x
1472 * MS <- SGSN: Attach Reject
1473 */
1474 var BSSGP_ConnHdlr vc_conn;
1475 f_init();
1476 f_sleep(1.0);
1477 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1478 vc_conn.done;
1479}
1480
Alexander Couzenscf818962018-06-05 18:00:00 +02001481private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1482 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1483}
1484
1485testcase TC_attach_check_subscriber_list() runs on test_CT {
1486 /* MS <-> SGSN: Attach
1487 * VTY -> SGSN: Check if MS is in subscriber cache
1488 */
1489 var BSSGP_ConnHdlr vc_conn;
1490 var integer id := 34;
1491 var charstring imsi := hex2str(f_gen_imsi(id));
1492
1493 f_init();
1494 f_sleep(1.0);
1495 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], id);
1496 vc_conn.done;
1497
1498 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1499 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1500}
1501
Alexander Couzensf9858652018-06-07 16:14:53 +02001502private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1503 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1504 var BssgpDecoded bd;
1505
1506 /* unregister the old IMSI */
1507 f_bssgp_client_unregister(g_pars.imsi);
1508 /* Simulate a foreign IMSI */
1509 g_pars.imsi := '001010123456789'H;
1510 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
1511
1512 /* there is no auth */
1513 g_pars.net.expect_auth := false;
1514
1515 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
1516 f_gmm_auth();
1517 alt {
1518 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1519 setverdict(fail, "Received unexpected GMM Attach REJECT");
1520 }
1521 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
1522 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
1523 BSSGP.send(ts_GMM_ATTACH_COMPL);
1524 setverdict(pass);
1525 }
1526 }
1527}
1528testcase TC_attach_closed_add_vty() runs on test_CT {
1529 /* VTY-> SGSN: policy close
1530 * MS -> SGSN: Attach Request
1531 * MS <- SGSN: Identity Request IMSI
1532 * MS -> SGSN: Identity Response IMSI
1533 * MS <- SGSN: Attach Reject
1534 * VTY-> SGSN: policy imsi-acl add IMSI
1535 * MS -> SGSN: Attach Request
1536 * MS <- SGSN: Identity Request IMSI
1537 * MS -> SGSN: Identity Response IMSI
1538 * MS <- SGSN: Identity Request IMEI
1539 * MS -> SGSN: Identity Response IMEI
1540 * MS <- SGSN: Attach Accept
1541 */
1542 var BSSGP_ConnHdlr vc_conn;
1543 f_init();
1544 f_sleep(1.0);
1545 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1546 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
1547 /* test with foreign IMSI: Must Reject */
1548 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
1549 vc_conn.done;
1550 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456789");
1551 /* test with same IMSI: Must Accept */
1552 vc_conn := f_start_handler(refers(f_TC_attach_closed_imsi_added), testcasename(), g_gb[0], 10);
1553 vc_conn.done;
1554}
1555
Alexander Couzens0085bd72018-06-12 19:08:44 +02001556/* Attempt an attach, but never answer a Attach Complete */
1557private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1558 var integer count_req := 0;
1559
1560 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1561 f_gmm_auth();
1562
1563 alt {
1564 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1565 /* break */
1566 }
1567 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
1568 /* ignore */
1569 count_req := count_req + 1;
1570 repeat;
1571 }
1572 }
1573 if (count_req != 5) {
1574 setverdict(fail, "Did not received GMM Attach Complete.");
1575 }
1576 setverdict(pass);
1577}
1578
1579testcase TC_attach_check_complete_resend() runs on test_CT {
1580 /* MS -> SGSN: Attach Request IMSI
1581 * MS <- SGSN: Identity Request *
1582 * MS -> SGSN: Identity Response *
1583 * MS <- SGSN: Attach Complete 5x
1584 */
1585 var BSSGP_ConnHdlr vc_conn;
1586 f_init();
1587 f_sleep(1.0);
1588 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb[0], 36, 60.0);
1589 vc_conn.done;
1590}
1591
Harald Welte5ac31492018-02-15 20:39:13 +01001592control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001593 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001594 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001595 execute( TC_attach_umts_aka_umts_res() );
1596 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001597 execute( TC_attach_auth_id_timeout() );
1598 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001599 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001600 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001601 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001602 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001603 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001604 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001605 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001606 execute( TC_attach_no_imsi_response() );
Alexander Couzensf9858652018-06-07 16:14:53 +02001607 execute( TC_attach_closed_add_vty(), 10.0 );
Alexander Couzenscf818962018-06-05 18:00:00 +02001608 execute( TC_attach_check_subscriber_list(), 10.0 );
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001609 execute( TC_attach_detach_check_subscriber_list(), 10.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02001610 execute( TC_attach_check_complete_resend() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001611 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001612 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1613 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1614 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001615 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001616 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001617 execute( TC_detach_unknown_nopoweroff() );
1618 execute( TC_detach_unknown_poweroff() );
1619 execute( TC_detach_nopoweroff() );
1620 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001621 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001622 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001623 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001624 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001625 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001626 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001627 execute( TC_attach_second_attempt() );
Harald Welte5ac31492018-02-15 20:39:13 +01001628}
Harald Welte96a33b02018-02-04 10:36:22 +01001629
1630
1631
1632}