blob: 96327180b1c2b81244a84c4fefdf648263e4742f [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 }
709 }
710}
711testcase TC_attach_closed() runs on test_CT {
712 var BSSGP_ConnHdlr vc_conn;
713 f_init();
714 f_sleep(1.0);
715 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
716 /* test with foreign IMSI: Must Reject */
Harald Welteb7c14e92018-02-17 09:29:16 +0100717 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb[0], 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100718 vc_conn.done;
719 /* test with home IMSI: Must Accept */
Harald Welteb7c14e92018-02-17 09:29:16 +0100720 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb[0], 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100721 vc_conn.done;
722}
723
Harald Welte04683d02018-02-16 22:43:45 +0100724/* Routing Area Update from Unknown TLLI -> REJECT */
725private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100726 var RoutingAreaIdentificationV old_ra := f_random_RAI();
727
Harald Welte23178c52018-02-17 09:36:33 +0100728 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 +0100729 alt {
730 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
731 setverdict(pass);
732 }
733 /* FIXME: Expect XID RESET? */
734 [] BSSGP.receive { repeat; }
735 }
736}
737testcase TC_rau_unknown() runs on test_CT {
738 var BSSGP_ConnHdlr vc_conn;
739 f_init();
740 f_sleep(1.0);
Harald Welteb7c14e92018-02-17 09:29:16 +0100741 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb[0], 11);
Harald Welte04683d02018-02-16 22:43:45 +0100742 vc_conn.done;
743}
744
Harald Welte91636de2018-02-17 10:16:14 +0100745private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
746 var BssgpDecoded bd;
747
748 /* first perform regular attach */
749 f_TC_attach(id);
750
751 /* then send RAU */
752 BSSGP.send(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit));
753 alt {
754 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
755 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept);
Alexander Couzens80ec1ea2018-05-12 16:44:36 +0200756 BSSGP.send(ts_GMM_RAU_COMPL);
Harald Welte91636de2018-02-17 10:16:14 +0100757 setverdict(pass);
758 }
759 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
760 setverdict(fail, "Unexpected RAU Reject");
761 }
762 [] BSSGP.receive { repeat; }
763 }
764}
765testcase TC_attach_rau() runs on test_CT {
766 var BSSGP_ConnHdlr vc_conn;
767 f_init();
768 f_sleep(1.0);
769 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb[0], 12);
770 vc_conn.done;
771}
Harald Welte04683d02018-02-16 22:43:45 +0100772
Harald Welte6abb9fe2018-02-17 15:24:48 +0100773/* general GPRS DETACH helper */
774function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge) runs on BSSGP_ConnHdlr {
775 var BssgpDecoded bd;
776 timer T := 5.0;
777 BSSGP.send(ts_GMM_DET_REQ_MO(detach_type, power_off));
778 if (expect_purge) {
779 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
780 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
781 }
782 T.start;
783 alt {
784 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
785 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
786 }
787 [power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
788 g_pars.ra := omit;
789 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
790 /* TODO: check if any PDP contexts are deactivated on network side? */
791 }
792 [power_off] T.timeout {
793 setverdict(pass);
794 }
795 [not power_off] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
796 g_pars.ra := omit;
797 setverdict(pass);
798 /* TODO: check if any PDP contexts are deactivated on network side? */
799 }
800 [] BSSGP.receive { repeat; }
801 }
802}
803
804/* IMSI DETACH (non-power-off) for unknown TLLI */
805private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
806 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
807}
808testcase TC_detach_unknown_nopoweroff() runs on test_CT {
809 var BSSGP_ConnHdlr vc_conn;
810 f_init();
811 f_sleep(1.0);
812 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb[0], 13);
813 vc_conn.done;
814}
815
816/* IMSI DETACH (power-off) for unknown TLLI */
817private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
818 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
819}
820testcase TC_detach_unknown_poweroff() runs on test_CT {
821 var BSSGP_ConnHdlr vc_conn;
822 f_init();
823 f_sleep(1.0);
824 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb[0], 14);
825 vc_conn.done;
826}
827
828/* IMSI DETACH (non-power-off) for known TLLI */
829private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
830 /* first perform regular attach */
831 f_TC_attach(id);
832
833 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
834}
835testcase TC_detach_nopoweroff() runs on test_CT {
836 var BSSGP_ConnHdlr vc_conn;
837 f_init();
838 f_sleep(1.0);
839 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb[0], 15);
840 vc_conn.done;
841}
842
843/* IMSI DETACH (power-off) for known TLLI */
844private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
845 /* first perform regular attach */
846 f_TC_attach(id);
847
848 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
849}
850testcase TC_detach_poweroff() runs on test_CT {
851 var BSSGP_ConnHdlr vc_conn;
852 f_init();
853 f_sleep(1.0);
854 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb[0], 16);
855 vc_conn.done;
856}
857
Harald Welteeded9ad2018-02-17 20:57:34 +0100858type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100859 BIT3 tid, /* L3 Transaction ID */
860 BIT4 nsapi, /* SNDCP NSAPI */
861 BIT4 sapi, /* LLC SAPI */
862 QoSV qos, /* QoS parameters */
863 PDPAddressV addr, /* IP address */
864 octetstring apn optional, /* APN name */
865 ProtocolConfigOptionsV pco optional, /* protoco config opts */
866 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100867 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100868 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100869
Harald Welte822f9102018-02-18 20:39:06 +0100870 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
871 OCT4 ggsn_tei_u, /* GGSN TEI User */
872 octetstring ggsn_ip_c, /* GGSN IP Control */
873 octetstring ggsn_ip_u, /* GGSN IP User */
Harald Welteeded9ad2018-02-17 20:57:34 +0100874
Harald Welte822f9102018-02-18 20:39:06 +0100875 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
876 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
877 octetstring sgsn_ip_c optional, /* SGSN IP Control */
878 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +0100879};
880
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100881
882private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
883 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
884 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
885 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
886 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
887 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
888 f_gtp_register_teid(apars.ggsn_tei_c);
889 f_gtp_register_teid(apars.ggsn_tei_u);
890}
891
Harald Welte37692d82018-02-18 15:21:34 +0100892function f_pdp_ctx_act(inout PdpActPars apars) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100893 var boolean exp_rej := ispresent(apars.exp_rej_cause);
894 var Gtp1cUnitdata g_ud;
895
896 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
897 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100898 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
899 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
900 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
901 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
902 apars.sgsn_tei_c, apars.gtp_resp_cause,
903 apars.ggsn_tei_c, apars.ggsn_tei_u,
904 apars.nsapi,
905 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id));
Harald Welteeded9ad2018-02-17 20:57:34 +0100906 }
907 alt {
Harald Welte28307082018-02-18 12:14:18 +0100908 [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 +0100909 setverdict(pass);
910 }
Harald Welte28307082018-02-18 12:14:18 +0100911 [exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100912 setverdict(fail, "Unexpected PDP CTX ACT ACC");
913 }
Harald Welte28307082018-02-18 12:14:18 +0100914 [not exp_rej] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +0100915 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
916 }
Harald Welte28307082018-02-18 12:14:18 +0100917 [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 +0100918 setverdict(pass);
919 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +0100920 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +0100921 }
922}
923
Harald Welte6f203162018-02-18 22:04:55 +0100924function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
925 var boolean exp_rej := ispresent(apars.exp_rej_cause);
926 var Gtp1cUnitdata g_ud;
927
928 BSSGP.send(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
929 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
930 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
931 BSSGP.clear;
932 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
933 }
934 alt {
935 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
936 setverdict(pass);
937 }
938 [] as_xid(apars);
939 }
940}
941
Harald Welte57b9b7f2018-02-18 22:28:13 +0100942function f_pdp_ctx_deact_mt(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
943 var Gtp1cUnitdata g_ud;
944 var integer seq_nr := 23;
945 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
946
947 BSSGP.clear;
948 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, omit));
949
950 interleave {
951 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?))) {
952 BSSGP.send(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
953 }
954 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) { }
955 }
956}
957
Harald Welte6f203162018-02-18 22:04:55 +0100958
Harald Welteeded9ad2018-02-17 20:57:34 +0100959/* Table 10.5.156/3GPP TS 24.008 */
960template (value) QoSV t_QosDefault := {
961 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
962 delayClass := '100'B, /* best effort */
963 spare1 := '00'B,
964 precedenceClass := '010'B, /* normal */
965 spare2 := '0'B,
966 peakThroughput := '0000'B, /* subscribed */
967 meanThroughput := '00000'B, /* subscribed */
968 spare3 := '000'B,
969 deliverErroneusSDU := omit,
970 deliveryOrder := omit,
971 trafficClass := omit,
972 maxSDUSize := omit,
973 maxBitrateUplink := omit,
974 maxBitrateDownlink := omit,
975 sduErrorRatio := omit,
976 residualBER := omit,
977 trafficHandlingPriority := omit,
978 transferDelay := omit,
979 guaranteedBitRateUplink := omit,
980 guaranteedBitRateDownlink := omit,
981 sourceStatisticsDescriptor := omit,
982 signallingIndication := omit,
983 spare4 := omit,
984 maxBitrateDownlinkExt := omit,
985 guaranteedBitRateDownlinkExt := omit,
986 maxBitrateUplinkExt := omit,
987 guaranteedBitRateUplinkExt := omit,
988 maxBitrateDownlinkExt2 := omit,
989 guaranteedBitRateDownlinkExt2 := omit,
990 maxBitrateUplinkExt2 := omit,
991 guaranteedBitRateUplinkExt2 := omit
992}
993
994/* 10.5.6.4 / 3GPP TS 24.008 */
995template (value) PDPAddressV t_AddrIPv4dyn := {
996 pdpTypeOrg := '0001'B, /* IETF */
997 spare := '0000'B,
998 pdpTypeNum := '21'O, /* IPv4 */
999 addressInfo := omit
1000}
1001template (value) PDPAddressV t_AddrIPv6dyn := {
1002 pdpTypeOrg := '0001'B, /* IETF */
1003 spare := '0000'B,
1004 pdpTypeNum := '53'O, /* IPv6 */
1005 addressInfo := omit
1006}
1007
Harald Welte37692d82018-02-18 15:21:34 +01001008template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001009 tid := '000'B,
1010 nsapi := '0101'B, /* < 5 are reserved */
1011 sapi := '0011'B, /* 3/5/9/11 */
1012 qos := t_QosDefault,
1013 addr := t_AddrIPv4dyn,
1014 apn := omit,
1015 pco := omit,
1016 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001017 gtp_resp_cause := int2oct(128, 1),
1018 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001019
1020 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001021 ggsn_tei_c := f_rnd_octstring(4),
1022 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001023 ggsn_ip_c := f_inet_addr(ggsn_ip),
1024 ggsn_ip_u := f_inet_addr(ggsn_ip),
Harald Welteeded9ad2018-02-17 20:57:34 +01001025
Harald Welteeded9ad2018-02-17 20:57:34 +01001026 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001027 sgsn_tei_u := omit,
1028 sgsn_ip_c := omit,
1029 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001030}
1031
Harald Welte37692d82018-02-18 15:21:34 +01001032template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1033 connId := 1,
1034 remName := f_inet_ntoa(ip),
1035 remPort := GTP1U_PORT
1036}
1037
1038template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1039 connId := 1,
1040 remName := f_inet_ntoa(ip),
1041 remPort := GTP1C_PORT
1042}
1043
1044private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1045 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1046 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1047}
1048
1049private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
1050 [] BSSGP.receive(tr_BD_LLC(tr_LLC_XID(?, apars.sapi))) {
1051 repeat;
1052 }
1053}
1054
1055template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1056 pDU_SN_UNITDATA := {
1057 nsapi := nsapi,
1058 moreBit := ?,
1059 snPduType := '1'B,
1060 firstSegmentIndicator := ?,
1061 spareBit := ?,
1062 pcomp := ?,
1063 dcomp := ?,
1064 npduNumber := ?,
1065 segmentNumber := ?,
1066 npduNumberContinued := ?,
1067 dataSegmentSnUnitdataPdu := payload
1068 }
1069}
1070
1071/* simple case: single segment, no compression */
1072template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1073 pDU_SN_UNITDATA := {
1074 nsapi := nsapi,
1075 moreBit := '0'B,
1076 snPduType := '1'B,
1077 firstSegmentIndicator := '1'B,
1078 spareBit := '0'B,
1079 pcomp := '0000'B,
1080 dcomp := '0000'B,
1081 npduNumber := '0000'B,
1082 segmentNumber := '0000'B,
1083 npduNumberContinued := '00'O,
1084 dataSegmentSnUnitdataPdu := payload
1085 }
1086}
1087
1088/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1089private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1090 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1091 f_gtpu_send(apars, payload);
1092 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1093 alt {
1094 [] as_xid(apars);
1095 [] BSSGP.receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1096 }
1097}
1098
1099private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1100 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1101 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1102 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
1103 BSSGP.send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
1104 f_gtpu_send(apars, payload);
1105 /* Expect PDU via GTP from SGSN on simulated GGSN */
1106 alt {
1107 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1108 }
1109}
1110
Harald Welteeded9ad2018-02-17 20:57:34 +01001111private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001112 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001113
1114 /* first perform regular attach */
1115 f_TC_attach(id);
1116
1117 f_pdp_ctx_act(apars);
1118}
1119testcase TC_attach_pdp_act() runs on test_CT {
1120 var BSSGP_ConnHdlr vc_conn;
1121 f_init();
1122 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb[0], 17);
1123 vc_conn.done;
1124}
Harald Welteb2124b22018-02-16 22:26:56 +01001125
Harald Welte835b15f2018-02-18 14:39:11 +01001126/* PDP Context activation for not-attached subscriber; expect fail */
1127private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001128 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welte835b15f2018-02-18 14:39:11 +01001129 BSSGP.send(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1130 apars.apn, apars.pco));
1131 alt {
1132 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
1133 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
1134 setverdict(pass);
1135 }
1136 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1137 setverdict(fail, "Unexpected GTP PDP CTX ACT");
1138 }
1139 [] BSSGP.receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
1140 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
1141 }
1142 [] BSSGP.receive { repeat; }
1143 }
1144}
1145testcase TC_pdp_act_unattached() runs on test_CT {
1146 var BSSGP_ConnHdlr vc_conn;
1147 f_init();
1148 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb[0], 18);
1149 vc_conn.done;
1150}
1151
Harald Welte37692d82018-02-18 15:21:34 +01001152/* ATTACH + PDP CTX ACT + user plane traffic */
1153private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1154 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1155
1156 /* first perform regular attach */
1157 f_TC_attach(id);
1158 /* then activate PDP context */
1159 f_pdp_ctx_act(apars);
1160 /* then transceive a downlink PDU */
1161 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1162 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1163}
1164testcase TC_attach_pdp_act_user() runs on test_CT {
1165 var BSSGP_ConnHdlr vc_conn;
1166 f_init();
1167 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb[0], 19);
1168 vc_conn.done;
1169}
1170
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001171/* ATTACH + PDP CTX ACT; reject from GGSN */
1172private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1173 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1174
1175 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1176 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1177
1178 /* first perform regular attach */
1179 f_TC_attach(id);
1180 /* then activate PDP context */
1181 f_pdp_ctx_act(apars);
1182}
1183testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1184 var BSSGP_ConnHdlr vc_conn;
1185 f_init();
1186 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb[0], 20);
1187 vc_conn.done;
1188}
Harald Welte835b15f2018-02-18 14:39:11 +01001189
Harald Welte6f203162018-02-18 22:04:55 +01001190/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1191private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1192 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1193
1194 /* first perform regular attach */
1195 f_TC_attach(id);
1196 /* then activate PDP context */
1197 f_pdp_ctx_act(apars);
1198 /* then transceive a downlink PDU */
1199 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1200 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1201
1202 f_pdp_ctx_deact_mo(apars, '00'O);
1203}
1204testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1205 var BSSGP_ConnHdlr vc_conn;
1206 f_init();
1207 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb[0], 21);
1208 vc_conn.done;
1209}
1210
Harald Welte57b9b7f2018-02-18 22:28:13 +01001211/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1212private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1213 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1214
1215 /* first perform regular attach */
1216 f_TC_attach(id);
1217 /* then activate PDP context */
1218 f_pdp_ctx_act(apars);
1219 /* then transceive a downlink PDU */
1220 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1221 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1222
1223 f_pdp_ctx_deact_mt(apars, '00'O);
1224}
1225testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1226 var BSSGP_ConnHdlr vc_conn;
1227 f_init();
1228 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb[0], 22);
1229 vc_conn.done;
1230}
1231
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001232/* ATTACH + ATTACH (2nd) */
1233private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1234 g_pars.t_guard := 5.0;
1235
1236 /* first perform regular attach */
1237 f_TC_attach(id);
1238
1239 /* second to perform regular attach */
1240 f_TC_attach(id);
1241}
1242
1243
1244testcase TC_attach_second_attempt() runs on test_CT {
1245 var BSSGP_ConnHdlr vc_conn;
1246 f_init();
1247 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb[0], 22);
1248 vc_conn.done;
1249}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001250
Harald Welte5ac31492018-02-15 20:39:13 +01001251
Alexander Couzens5e307b42018-05-22 18:12:20 +02001252private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1253 /* MS: perform regular attach */
1254 f_TC_attach(id);
1255
1256 /* HLR: cancel the location request */
1257 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1258 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1259 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1260
1261 /* ensure no Detach Request got received */
1262 timer T := 5.0;
1263 T.start;
1264 alt {
1265 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
1266 T.stop;
1267 setverdict(fail, "Unexpected GMM Detach Request");
1268 }
1269 [] T.timeout {
1270 setverdict(pass);
1271 self.stop;
1272 }
1273 [] BSSGP.receive {
1274 repeat;
1275 }
1276 }
1277}
1278
1279testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1280 /* MS <-> SGSN: GMM Attach
1281 * HLR -> SGSN: Cancel Location Request
1282 * HLR <- SGSN: Cancel Location Ack
1283 */
1284 var BSSGP_ConnHdlr vc_conn;
1285 f_init();
1286 f_sleep(1.0);
1287 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb[0], 31);
1288 vc_conn.done;
1289}
1290
1291
Alexander Couzensc87967a2018-05-22 16:09:54 +02001292private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1293 /* MS: perform regular attach */
1294 f_TC_attach(id);
1295
1296 /* HLR: cancel the location request */
1297 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1298 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1299 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1300
1301 /* MS: receive a Detach Request */
1302 BSSGP.receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
1303 BSSGP.send(ts_GMM_DET_ACCEPT_MO);
1304
1305 setverdict(pass);
1306}
1307
1308testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1309 /* MS <-> SGSN: GMM Attach
1310 * HLR -> SGSN: Cancel Location Request
1311 * HLR <- SGSN: Cancel Location Ack
1312 * MS <- SGSN: Detach Request
1313 * SGSN-> MS: Detach Complete
1314 */
1315 var BSSGP_ConnHdlr vc_conn;
1316 f_init();
1317 f_sleep(1.0);
1318 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb[0], 29);
1319 vc_conn.done;
1320}
1321
1322
Alexander Couzens6c47f292018-05-22 17:09:49 +02001323private function f_hlr_location_cancel_request_unknown_subscriber(
1324 charstring id,
1325 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1326
1327 /* HLR: cancel the location request */
1328 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1329
1330 /* cause 2 = IMSI_UNKNOWN */
1331 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1332
1333 setverdict(pass);
1334}
1335
1336private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001337 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001338}
1339
1340testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1341 /* HLR -> SGSN: Cancel Location Request
1342 * HLR <- SGSN: Cancel Location Error
1343 */
1344
1345 var BSSGP_ConnHdlr vc_conn;
1346 f_init();
1347 f_sleep(1.0);
1348 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb[0], 30);
1349 vc_conn.done;
1350}
1351
1352private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001353 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001354}
1355
1356testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1357 /* HLR -> SGSN: Cancel Location Request
1358 * HLR <- SGSN: Cancel Location Error
1359 */
1360
1361 var BSSGP_ConnHdlr vc_conn;
1362 f_init();
1363 f_sleep(1.0);
1364 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb[0], 30);
1365 vc_conn.done;
1366}
1367
1368
1369
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001370/* Attempt an attach, but loose the Identification Request (IMEI) */
1371private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1372 var integer count_req := 0;
1373 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1374
1375 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1376
1377 alt {
1378 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1379 /* break */
1380 }
1381 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1382 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1383 BSSGP.send(ts_GMM_ID_RESP(mi));
1384 repeat;
1385 }
1386 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1387 /* ignore ID REQ IMEI */
1388 count_req := count_req + 1;
1389 repeat;
1390 }
1391 }
1392 if (count_req != 5) {
1393 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
1394 }
1395 setverdict(pass);
1396}
1397
1398testcase TC_attach_no_imei_response() runs on test_CT {
1399 /* MS -> SGSN: Attach Request IMSI
1400 * MS <- SGSN: Identity Request IMSI (optional)
1401 * MS -> SGSN: Identity Response IMSI (optional)
1402 * MS <- SGSN: Identity Request IMEI
1403 * MS -x SGSN: no response
1404 * MS <- SGSN: re-send: Identity Request IMEI 4x
1405 * MS <- SGSN: Attach Reject
1406 */
1407 var BSSGP_ConnHdlr vc_conn;
1408 f_init();
1409 f_sleep(1.0);
1410 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb[0], 32, 60.0);
1411 vc_conn.done;
1412}
1413
Alexander Couzens53f20562018-06-12 16:24:12 +02001414/* Attempt an attach, but loose the Identification Request (IMSI) */
1415private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1416 var integer count_req := 0;
1417 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1418
1419 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1420 g_pars.p_tmsi := 'c0000035'O;
1421
1422 BSSGP.send(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
1423
1424 alt {
1425 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1426 /* break */
1427 }
1428 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1429 /* ignore ID REQ IMSI */
1430 count_req := count_req + 1;
1431 repeat;
1432 }
1433 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1434 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1435 BSSGP.send(ts_GMM_ID_RESP(mi));
1436 repeat;
1437 }
1438 }
1439 if (count_req != 5) {
1440 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
1441 }
1442 setverdict(pass);
1443}
1444
1445testcase TC_attach_no_imsi_response() runs on test_CT {
1446 /* MS -> SGSN: Attach Request TMSI (unknown)
1447 * MS <- SGSN: Identity Request IMEI (optional)
1448 * MS -> SGSN: Identity Response IMEI (optional)
1449 * MS <- SGSN: Identity Request IMSI
1450 * MS -x SGSN: no response
1451 * MS <- SGSN: re-send: Identity Request IMSI 4x
1452 * MS <- SGSN: Attach Reject
1453 */
1454 var BSSGP_ConnHdlr vc_conn;
1455 f_init();
1456 f_sleep(1.0);
1457 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb[0], 35, 60.0);
1458 vc_conn.done;
1459}
1460
Harald Welte5ac31492018-02-15 20:39:13 +01001461control {
Harald Welte5b7c8122018-02-16 21:48:17 +01001462 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01001463 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02001464 execute( TC_attach_umts_aka_umts_res() );
1465 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001466 execute( TC_attach_auth_id_timeout() );
1467 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01001468 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01001469 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01001470 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01001471 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01001472 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01001473 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001474 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02001475 execute( TC_attach_no_imsi_response() );
Alexander Couzens5e307b42018-05-22 18:12:20 +02001476 execute( TC_hlr_location_cancel_request_update(), 10.0 );
Alexander Couzens234c5882018-05-29 15:48:44 +02001477 execute( TC_hlr_location_cancel_request_withdraw(), 10.0 );
1478 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 10.0 );
1479 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 10.0 );
Harald Welte04683d02018-02-16 22:43:45 +01001480 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01001481 execute( TC_attach_rau() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01001482 execute( TC_detach_unknown_nopoweroff() );
1483 execute( TC_detach_unknown_poweroff() );
1484 execute( TC_detach_nopoweroff() );
1485 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01001486 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01001487 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01001488 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001489 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01001490 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01001491 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001492 execute( TC_attach_second_attempt() );
Harald Welte5ac31492018-02-15 20:39:13 +01001493}
Harald Welte96a33b02018-02-04 10:36:22 +01001494
1495
1496
1497}