blob: c34cf59d119df11613a704d6020f2648f282479e [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";
Alexander Couzens2c12b242018-07-31 00:30:11 +020046
Alexander Couzensf3c1b412018-08-24 00:42:51 +020047 NSConfigurations mp_nsconfig := {
48 {
49 local_udp_port := 21010,
50 local_ip := "127.0.0.1",
51 remote_udp_port := 23000,
52 remote_ip := "127.0.0.1",
53 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020054 nsei := 96,
55 role_sgsn := false,
56 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020057 },
58 {
59 local_udp_port := 21011,
60 local_ip := "127.0.0.1",
61 remote_udp_port := 23000,
62 remote_ip := "127.0.0.1",
63 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020064 nsei := 97,
65 role_sgsn := false,
66 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020067 },
68 {
69 local_udp_port := 21012,
70 local_ip := "127.0.0.1",
71 remote_udp_port := 23000,
72 remote_ip := "127.0.0.1",
73 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020074 nsei := 98,
75 role_sgsn := false,
76 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020077 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020078 };
Harald Welte5ac31492018-02-15 20:39:13 +010079};
80
81type record GbInstance {
82 NS_CT vc_NS,
83 BSSGP_CT vc_BSSGP,
84 BssgpConfig cfg
85};
Harald Welte96a33b02018-02-04 10:36:22 +010086
Alexander Couzens51114d12018-07-31 18:41:56 +020087type record length(3) of GbInstance GbInstances;
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088type record length(3) of NSConfiguration NSConfigurations;
Alexander Couzens51114d12018-07-31 18:41:56 +020089type record length(3) of BssgpCellId BssgpCellIds;
90
Harald Welte96a33b02018-02-04 10:36:22 +010091type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +020092 var GbInstances g_gb;
Harald Welte96a33b02018-02-04 10:36:22 +010093
Harald Welte5ac31492018-02-15 20:39:13 +010094 var GSUP_Emulation_CT vc_GSUP;
95 var IPA_Emulation_CT vc_GSUP_IPA;
96 /* only to get events from IPA underneath GSUP */
97 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010098
Harald Welteeded9ad2018-02-17 20:57:34 +010099 var GTP_Emulation_CT vc_GTP;
100
Harald Weltebd194722018-02-16 22:11:08 +0100101 port TELNETasp_PT SGSNVTY;
102
Harald Welte96a33b02018-02-04 10:36:22 +0100103 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200104 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100105};
106
Harald Welteeded9ad2018-02-17 20:57:34 +0100107type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100108 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100109 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200110 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100111}
112
113type record SGSN_ConnHdlrNetworkPars {
114 boolean expect_ptmsi,
115 boolean expect_auth,
116 boolean expect_ciph
117};
118
119type record BSSGP_ConnHdlrPars {
120 /* IMEI of the simulated ME */
121 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200122 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100123 hexstring imsi,
124 /* MSISDN of the simulated MS (probably unused) */
125 hexstring msisdn,
126 /* P-TMSI allocated to the simulated MS */
127 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100128 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100129 /* TLLI of the simulated MS */
130 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100131 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100132 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200133 BssgpCellIds bssgp_cell_id,
Harald Welte5ac31492018-02-15 20:39:13 +0100134 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100135 SGSN_ConnHdlrNetworkPars net,
136 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100137};
138
Alexander Couzens89508702018-07-31 04:16:10 +0200139private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200140 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200141 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
142
143 var RoutingAreaIdentificationV ret := {
144 mccDigit1 := mcc_mnc[0],
145 mccDigit2 := mcc_mnc[1],
146 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200147 mncDigit3 := mcc_mnc[3],
148 mncDigit1 := mcc_mnc[4],
149 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200150 lac := int2oct(cell_id.ra_id.lai.lac, 16),
151 rac := int2oct(cell_id.ra_id.rac, 8)
152 }
153 return ret;
154};
155
Alexander Couzens51114d12018-07-31 18:41:56 +0200156private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
157 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
158 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100159 /* connect lower end of BSSGP emulation with NS upper port */
160 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
161 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
162 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
163
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200164 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100165 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
166}
167
168private function f_init_gsup(charstring id) runs on test_CT {
169 id := id & "-GSUP";
170 var GsupOps ops := {
171 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
172 };
173
174 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
175 vc_GSUP := GSUP_Emulation_CT.create(id);
176
177 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
178 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
179 /* we use this hack to get events like ASP_IPA_EVENT_UP */
180 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
181
182 vc_GSUP.start(GSUP_Emulation.main(ops, id));
183 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
184
185 /* wait for incoming connection to GSUP port before proceeding */
186 timer T := 10.0;
187 T.start;
188 alt {
189 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
190 [] T.timeout {
191 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200192 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100193 }
194 }
195}
196
Harald Welteeded9ad2018-02-17 20:57:34 +0100197private function f_init_gtp(charstring id) runs on test_CT {
198 id := id & "-GTP";
199
200 var GtpEmulationCfg gtp_cfg := {
201 gtpc_bind_ip := mp_ggsn_ip,
202 gtpc_bind_port := GTP1C_PORT,
203 gtpu_bind_ip := mp_ggsn_ip,
204 gtpu_bind_port := GTP1U_PORT,
205 sgsn_role := false
206 };
207
208 vc_GTP := GTP_Emulation_CT.create(id);
209 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
210}
211
Harald Weltebd194722018-02-16 22:11:08 +0100212private function f_init_vty() runs on test_CT {
213 map(self:SGSNVTY, system:SGSNVTY);
214 f_vty_set_prompts(SGSNVTY);
215 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200216 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100217 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
218}
219
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200220private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
221 if (enable) {
222 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
223 } else {
224 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
225 }
226}
227
Harald Weltebd194722018-02-16 22:11:08 +0100228
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200229/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
230function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte96a33b02018-02-04 10:36:22 +0100231 if (g_initialized == true) {
232 return;
233 }
234 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100235 g_gb[0].cfg := {
236 nsei := 96,
237 bvci := 196,
238 cell_id := {
239 ra_id := {
240 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100241 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100242 rac := 0
243 },
244 cell_id := 20960
245 },
246 sgsn_role := false
247 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200248 g_gb[1].cfg := {
249 nsei := 97,
250 bvci := 210,
251 cell_id := {
252 ra_id := {
253 lai := {
254 mcc_mnc := mcc_mnc, lac := 13200},
255 rac := 0
256 },
257 cell_id := 20961
258 },
259 sgsn_role := false
260 };
261 g_gb[2].cfg := {
262 nsei := 98,
263 bvci := 220,
264 cell_id := {
265 ra_id := {
266 lai := {
267 mcc_mnc := mcc_mnc, lac := 13300},
268 rac := 0
269 },
270 cell_id := 20962
271 },
272 sgsn_role := false
273 };
Harald Welte96a33b02018-02-04 10:36:22 +0100274
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200275 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200276 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
277 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
278 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte5ac31492018-02-15 20:39:13 +0100279 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100280 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200281 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100282}
Harald Welte96a33b02018-02-04 10:36:22 +0100283
Harald Welte5ac31492018-02-15 20:39:13 +0100284type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
285
286/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200287function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100288 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100289runs on test_CT return BSSGP_ConnHdlr {
290 var BSSGP_ConnHdlr vc_conn;
291 var SGSN_ConnHdlrNetworkPars net_pars := {
292 expect_ptmsi := true,
293 expect_auth := true,
294 expect_ciph := false
295 };
296 var BSSGP_ConnHdlrPars pars := {
297 imei := f_gen_imei(imsi_suffix),
298 imsi := f_gen_imsi(imsi_suffix),
299 msisdn := f_gen_msisdn(imsi_suffix),
300 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100301 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100302 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100303 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100304 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200305 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Harald Welte5ac31492018-02-15 20:39:13 +0100306 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100307 net := net_pars,
308 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100309 };
310
311 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200312 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
313 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
314 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
315 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
316 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
317 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100318
319 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
320 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
321
Harald Welteeded9ad2018-02-17 20:57:34 +0100322 connect(vc_conn:GTP, vc_GTP:CLIENT);
323 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
324
Harald Welte5ac31492018-02-15 20:39:13 +0100325 vc_conn.start(f_handler_init(fn, id, pars));
326 return vc_conn;
327}
328
Harald Welte62e29582018-02-16 21:17:11 +0100329private altstep as_Tguard() runs on BSSGP_ConnHdlr {
330 [] g_Tguard.timeout {
331 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200332 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100333 }
334}
335
Harald Welte5ac31492018-02-15 20:39:13 +0100336/* first function called in every ConnHdlr */
337private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
338runs on BSSGP_ConnHdlr {
339 /* do some common stuff like setting up g_pars */
340 g_pars := pars;
341
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200342 llc := f_llc_create(false);
343
Harald Welte5ac31492018-02-15 20:39:13 +0100344 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200345 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100346 /* tell GSUP dispatcher to send this IMSI to us */
347 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100348 /* tell GTP dispatcher to send this IMSI to us */
349 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100350
Harald Welte62e29582018-02-16 21:17:11 +0100351 g_Tguard.start(pars.t_guard);
352 activate(as_Tguard());
353
Harald Welte5ac31492018-02-15 20:39:13 +0100354 /* call the user-supplied test case function */
355 fn.apply(id);
356 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100357}
358
359/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100360 * Detach without Attach
361 * SM procedures without attach / RAU
362 * ATTACH / RAU
363 ** with / without authentication
364 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100365 * re-transmissions of LLC frames
366 * PDP Context activation
367 ** with different GGSN config in SGSN VTY
368 ** with different PDP context type (v4/v6/v46)
369 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100370 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100371 */
372
373testcase TC_wait_ns_up() runs on test_CT {
374 f_init();
375 f_sleep(20.0);
376}
377
Harald Weltea05b8072019-04-23 22:35:05 +0200378function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
379 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
380 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
381}
382
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200383function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
384 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
385 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
386 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Harald Weltea05b8072019-04-23 22:35:05 +0200387 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u));
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200388}
389
Harald Welteca362462019-05-02 20:11:21 +0200390altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100391 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welteca362462019-05-02 20:11:21 +0200392 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100393 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteca362462019-05-02 20:11:21 +0200394 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100395 repeat;
396 }
Harald Welteca362462019-05-02 20:11:21 +0200397 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Harald Welte5ac31492018-02-15 20:39:13 +0100398 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welteca362462019-05-02 20:11:21 +0200399 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100400 repeat;
401 }
402}
Harald Welte96a33b02018-02-04 10:36:22 +0100403
Harald Welteca362462019-05-02 20:11:21 +0200404/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
405function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
406runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
407 var BssgpDecoded bd;
408 var PDU_L3_SGSN_MS l3_mt;
409 alt {
410 [] BSSGP[gb_idx].receive(tr_BD_L3_MT(rx_tpl)) -> value bd {
411 l3_mt := bd.l3_mt;
412 }
413 }
414 return l3_mt;
415}
416
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200417/* perform GMM authentication (if expected).
418 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
419 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200420function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100421 var PDU_L3_MS_SGSN l3_mo;
422 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200423 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100424 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200425 var GSUP_IE auth_tuple;
426 var template AuthenticationParameterAUTNTLV autn;
427
428 if (umts_aka_challenge) {
429 g_pars.vec := f_gen_auth_vec_3g();
430 autn := {
431 elementIdentifier := '28'O,
432 lengthIndicator := lengthof(g_pars.vec.autn),
433 autnValue := g_pars.vec.autn
434 };
435
436 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
437 g_pars.vec.sres,
438 g_pars.vec.kc,
439 g_pars.vec.ik,
440 g_pars.vec.ck,
441 g_pars.vec.autn,
442 g_pars.vec.res));
443 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
444 } else {
445 g_pars.vec := f_gen_auth_vec_2g();
446 autn := omit;
447 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
448 g_pars.vec.sres,
449 g_pars.vec.kc));
450 log("GSUP sends only 2G auth tuple", auth_tuple);
451 }
Harald Welteca362462019-05-02 20:11:21 +0200452
Harald Welte5ac31492018-02-15 20:39:13 +0100453 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
454 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200455
456 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
457 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200458 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100459 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200460 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
461
462 if (umts_aka_challenge and not force_gsm_sres) {
463 /* set UMTS response instead */
464 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
465 valueField := substr(g_pars.vec.res, 0, 4)
466 };
467 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
468 elementIdentifier := '21'O,
469 lengthIndicator := lengthof(g_pars.vec.res) - 4,
470 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
471 };
472 }
473
474 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100475 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
476 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
477 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
478 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
479 }
Harald Welteca362462019-05-02 20:11:21 +0200480 f_send_l3_gmm_llc(l3_mo, gb_idx);
Harald Welte76dee092018-02-16 22:12:59 +0100481 } else {
482 /* wait for identity procedure */
483 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100484 }
Harald Welte76dee092018-02-16 22:12:59 +0100485
Harald Welte5ac31492018-02-15 20:39:13 +0100486 deactivate(di);
487}
488
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200489function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100490 g_pars.p_tmsi := p_tmsi;
491 /* update TLLI */
492 g_pars.tlli_old := g_pars.tlli;
493 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200494 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100495}
496
Harald Welte04683d02018-02-16 22:43:45 +0100497function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
498 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100499 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200500 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100501 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200502 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200503 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100504 }
Harald Welte04683d02018-02-16 22:43:45 +0100505 g_pars.ra := aa.routingAreaIdentification;
506 if (ispresent(aa.allocatedPTMSI)) {
507 if (not g_pars.net.expect_ptmsi) {
508 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200509 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100510 }
Harald Weltef70997d2018-02-17 10:11:19 +0100511 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100512 }
513 if (ispresent(aa.msIdentity)) {
514 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200515 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100516 }
517 /* P-TMSI.sig */
518 if (ispresent(aa.ptmsiSignature)) {
519 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
520 }
521 /* updateTimer */
522 // aa.readyTimer
523 /* T3302, T3319, T3323, T3312_ext, T3324 */
524}
525
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200526function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100527 /* mandatory IE */
528 g_pars.ra := ra.routingAreaId;
529 if (ispresent(ra.allocatedPTMSI)) {
530 if (not g_pars.net.expect_ptmsi) {
531 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200532 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100533 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200534 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100535 }
536 if (ispresent(ra.msIdentity)) {
537 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200538 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100539 }
540 /* P-TMSI.sig */
541 if (ispresent(ra.ptmsiSignature)) {
542 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
543 }
544 /* updateTimer */
545 // aa.readyTimer
546 /* T3302, T3319, T3323, T3312_ext, T3324 */
547}
548
549
Harald Welte5a4fa042018-02-16 20:59:21 +0100550function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
551 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
552}
553
Harald Welte23178c52018-02-17 09:36:33 +0100554/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100555private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100556 if (ispresent(g_pars.p_tmsi)) {
557 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
558 } else {
559 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
560 }
561}
562
Harald Welte311ec272018-02-17 09:40:03 +0100563private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100564 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100565 /* Expect MSC to perform LU with HLR */
566 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100567 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
568 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
569 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100570 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
571 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
572}
573
Harald Welteca362462019-05-02 20:11:21 +0200574friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100575 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200576 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welteca362462019-05-02 20:11:21 +0200577 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100578
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200579 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
580 * 3G auth vectors */
581 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
582 /* The thing is, if the solSACapability is 'omit', then the
583 * revisionLevelIndicatior is at the wrong place! */
584 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
585
Harald Welteca362462019-05-02 20:11:21 +0200586 f_send_l3_gmm_llc(attach_req, gb_idx);
587 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200588 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100589 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100590
Harald Welteca362462019-05-02 20:11:21 +0200591 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
592 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
593
Harald Welte04683d02018-02-16 22:43:45 +0100594 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welteca362462019-05-02 20:11:21 +0200595 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL, gb_idx);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200596}
597
598private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
599 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100600 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100601}
602
603testcase TC_attach() runs on test_CT {
604 var BSSGP_ConnHdlr vc_conn;
605 f_init();
606 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200607 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100608 vc_conn.done;
609}
610
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100611testcase TC_attach_mnc3() runs on test_CT {
612 var BSSGP_ConnHdlr vc_conn;
613 f_init('023042'H);
614 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200615 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100616 vc_conn.done;
617}
618
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200619private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
620 f_gmm_attach(true, false);
621 setverdict(pass);
622}
623testcase TC_attach_umts_aka_umts_res() runs on test_CT {
624 var BSSGP_ConnHdlr vc_conn;
625 f_init();
626 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200627 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200628 vc_conn.done;
629}
630
631private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
632 f_gmm_attach(true, true);
633 setverdict(pass);
634}
635testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
636 var BSSGP_ConnHdlr vc_conn;
637 f_init();
638 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200639 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200640 vc_conn.done;
641}
642
Harald Welte5b7c8122018-02-16 21:48:17 +0100643/* MS never responds to ID REQ, expect ATTACH REJECT */
644private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100645 var RoutingAreaIdentificationV old_ra := f_random_RAI();
646
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200647 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100648 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200649 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100650 /* don't send ID Response */
651 repeat;
652 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200653 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('09'O))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100654 setverdict(pass);
655 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200656 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100657 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200658 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100659 }
660 }
661}
662testcase TC_attach_auth_id_timeout() runs on test_CT {
663 var BSSGP_ConnHdlr vc_conn;
664 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200665 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb, 2, 40.0);
Harald Welte5b7c8122018-02-16 21:48:17 +0100666 vc_conn.done;
667}
668
669/* HLR never responds to SAI REQ, expect ATTACH REJECT */
670private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100671 var RoutingAreaIdentificationV old_ra := f_random_RAI();
672
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200673 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100674 alt {
675 [] as_mm_identity();
676 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
677 }
678 /* don't send SAI-response from HLR */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200679 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Welte5b7c8122018-02-16 21:48:17 +0100680 setverdict(pass);
681}
682testcase TC_attach_auth_sai_timeout() runs on test_CT {
683 var BSSGP_ConnHdlr vc_conn;
684 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200685 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100686 vc_conn.done;
687}
688
Harald Weltefe253882018-02-17 09:25:00 +0100689/* HLR rejects SAI, expect ATTACH REJECT */
690private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100691 var RoutingAreaIdentificationV old_ra := f_random_RAI();
692
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200693 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100694 alt {
695 [] as_mm_identity();
696 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
697 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
698 }
699 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200700 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?)));
Harald Weltefe253882018-02-17 09:25:00 +0100701 setverdict(pass);
702}
703testcase TC_attach_auth_sai_reject() runs on test_CT {
704 var BSSGP_ConnHdlr vc_conn;
705 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200706 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100707 vc_conn.done;
708}
709
Harald Welte5b7c8122018-02-16 21:48:17 +0100710/* HLR never responds to UL REQ, expect ATTACH REJECT */
711private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100712 var BssgpDecoded bd;
Harald Welte5b7c8122018-02-16 21:48:17 +0100713 var RoutingAreaIdentificationV old_ra := f_random_RAI();
714
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200715 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100716 f_gmm_auth();
717 /* Expect MSC to perform LU with HLR */
718 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
719 /* Never follow-up with ISD_REQ or UL_RES */
720 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200721 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100722 setverdict(pass);
723 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200724 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100725 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100726 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200727 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100728 }
729 }
730}
731testcase TC_attach_gsup_lu_timeout() runs on test_CT {
732 var BSSGP_ConnHdlr vc_conn;
733 f_init();
734 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200735 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100736 vc_conn.done;
737}
738
Harald Welteb7c14e92018-02-17 09:29:16 +0100739/* HLR rejects UL REQ, expect ATTACH REJECT */
740private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
741 var BssgpDecoded bd;
Harald Welteb7c14e92018-02-17 09:29:16 +0100742 var RoutingAreaIdentificationV old_ra := f_random_RAI();
743
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200744 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100745 f_gmm_auth();
746 /* Expect MSC to perform LU with HLR */
747 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
748 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
749 }
750 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200751 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100752 setverdict(pass);
753 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200754 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welteb7c14e92018-02-17 09:29:16 +0100755 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
756 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200757 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100758 }
759 }
760}
761testcase TC_attach_gsup_lu_reject() runs on test_CT {
762 var BSSGP_ConnHdlr vc_conn;
763 f_init();
764 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200765 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100766 vc_conn.done;
767}
768
769
Harald Welte3823e2e2018-02-16 21:53:48 +0100770/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
771private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100772 var BssgpDecoded bd;
Harald Welte3823e2e2018-02-16 21:53:48 +0100773 var RoutingAreaIdentificationV old_ra := f_random_RAI();
774
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200775 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100776 f_gmm_auth();
777 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100778 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100779
Alexander Couzens0e510e62018-07-28 23:06:00 +0200780 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100781 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
782 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200783 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100784 setverdict(pass);
785}
Harald Welte3823e2e2018-02-16 21:53:48 +0100786testcase TC_attach_combined() runs on test_CT {
787 var BSSGP_ConnHdlr vc_conn;
788 f_init();
789 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200790 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100791 vc_conn.done;
792}
793
Harald Welte76dee092018-02-16 22:12:59 +0100794/* Attempt of GPRS ATTACH in 'accept all' mode */
795private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100796 var BssgpDecoded bd;
Harald Welte76dee092018-02-16 22:12:59 +0100797 var RoutingAreaIdentificationV old_ra := f_random_RAI();
798
799 g_pars.net.expect_auth := false;
800
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200801 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100802 f_gmm_auth();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200803 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
Harald Welte04683d02018-02-16 22:43:45 +0100804 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
805 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200806 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100807 setverdict(pass);
808}
809testcase TC_attach_accept_all() runs on test_CT {
810 var BSSGP_ConnHdlr vc_conn;
811 f_init();
812 f_sleep(1.0);
813 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200814 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100815 vc_conn.done;
816}
Harald Welte5b7c8122018-02-16 21:48:17 +0100817
Harald Welteb2124b22018-02-16 22:26:56 +0100818/* Attempt of GPRS ATTACH in 'accept all' mode */
819private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100820 var RoutingAreaIdentificationV old_ra := f_random_RAI();
821
822 /* Simulate a foreign IMSI */
823 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200824 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100825
826 g_pars.net.expect_auth := false;
827
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200828 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100829 alt {
830 [] as_mm_identity();
Alexander Couzens0e510e62018-07-28 23:06:00 +0200831 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT('07'O))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100832 setverdict(pass);
833 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200834 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Harald Welteb2124b22018-02-16 22:26:56 +0100835 setverdict(pass);
836 }
Alexander Couzens0e510e62018-07-28 23:06:00 +0200837 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200838 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200839 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200840 }
Harald Welteb2124b22018-02-16 22:26:56 +0100841 }
842}
843testcase TC_attach_closed() runs on test_CT {
844 var BSSGP_ConnHdlr vc_conn;
845 f_init();
846 f_sleep(1.0);
847 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
848 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200849 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100850 vc_conn.done;
851 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200852 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100853 vc_conn.done;
854}
855
Harald Welte04683d02018-02-16 22:43:45 +0100856/* Routing Area Update from Unknown TLLI -> REJECT */
857private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100858 var RoutingAreaIdentificationV old_ra := f_random_RAI();
859
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200860 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +0100861 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +0200862 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT('0a'O))) {
Harald Welte04683d02018-02-16 22:43:45 +0100863 setverdict(pass);
864 }
865 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200866 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100867 }
868}
869testcase TC_rau_unknown() runs on test_CT {
870 var BSSGP_ConnHdlr vc_conn;
871 f_init();
872 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200873 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100874 vc_conn.done;
875}
876
Harald Welte91636de2018-02-17 10:16:14 +0100877private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
878 var BssgpDecoded bd;
879
880 /* first perform regular attach */
881 f_TC_attach(id);
882
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200883 f_routing_area_update(g_pars.ra);
884
Harald Welte91636de2018-02-17 10:16:14 +0100885}
886testcase TC_attach_rau() runs on test_CT {
887 var BSSGP_ConnHdlr vc_conn;
888 f_init();
889 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200890 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100891 vc_conn.done;
892}
Harald Welte04683d02018-02-16 22:43:45 +0100893
Harald Welte6abb9fe2018-02-17 15:24:48 +0100894/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200895function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100896 var BssgpDecoded bd;
897 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200898 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100899 if (expect_purge) {
900 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
901 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
902 }
903 T.start;
904 alt {
905 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
906 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200907 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100908 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200909 [power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100910 g_pars.ra := omit;
911 setverdict(fail, "Unexpected ATTACH ACCEPT in no-power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200912 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100913 /* TODO: check if any PDP contexts are deactivated on network side? */
914 }
915 [power_off] T.timeout {
916 setverdict(pass);
917 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200918 [not power_off] BSSGP[bssgp_index].receive(tr_BD_L3_MT(tr_GMM_DET_ACCEPT_MT)) -> value bd {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100919 g_pars.ra := omit;
920 setverdict(pass);
921 /* TODO: check if any PDP contexts are deactivated on network side? */
922 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200923 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +0100924 }
925}
926
927/* IMSI DETACH (non-power-off) for unknown TLLI */
928private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
929 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
930}
931testcase TC_detach_unknown_nopoweroff() runs on test_CT {
932 var BSSGP_ConnHdlr vc_conn;
933 f_init();
934 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200935 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100936 vc_conn.done;
937}
938
939/* IMSI DETACH (power-off) for unknown TLLI */
940private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
941 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
942}
943testcase TC_detach_unknown_poweroff() runs on test_CT {
944 var BSSGP_ConnHdlr vc_conn;
945 f_init();
946 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200947 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100948 vc_conn.done;
949}
950
951/* IMSI DETACH (non-power-off) for known TLLI */
952private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
953 /* first perform regular attach */
954 f_TC_attach(id);
955
956 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
957}
958testcase TC_detach_nopoweroff() runs on test_CT {
959 var BSSGP_ConnHdlr vc_conn;
960 f_init();
961 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200962 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100963 vc_conn.done;
964}
965
966/* IMSI DETACH (power-off) for known TLLI */
967private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
968 /* first perform regular attach */
969 f_TC_attach(id);
970
971 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
972}
973testcase TC_detach_poweroff() runs on test_CT {
974 var BSSGP_ConnHdlr vc_conn;
975 f_init();
976 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200977 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100978 vc_conn.done;
979}
980
Harald Welteeded9ad2018-02-17 20:57:34 +0100981type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +0100982 BIT3 tid, /* L3 Transaction ID */
983 BIT4 nsapi, /* SNDCP NSAPI */
984 BIT4 sapi, /* LLC SAPI */
985 QoSV qos, /* QoS parameters */
986 PDPAddressV addr, /* IP address */
987 octetstring apn optional, /* APN name */
988 ProtocolConfigOptionsV pco optional, /* protoco config opts */
989 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +0100990 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +0100991 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +0100992
Harald Welte822f9102018-02-18 20:39:06 +0100993 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
994 OCT4 ggsn_tei_u, /* GGSN TEI User */
995 octetstring ggsn_ip_c, /* GGSN IP Control */
996 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200997 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +0100998
Harald Welte822f9102018-02-18 20:39:06 +0100999 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1000 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1001 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1002 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001003};
1004
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001005
1006private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1007 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1008 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1009 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1010 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1011 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1012 f_gtp_register_teid(apars.ggsn_tei_c);
1013 f_gtp_register_teid(apars.ggsn_tei_u);
1014}
1015
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001016function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001017 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1018 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001019 var template Recovery_gtpc recovery := omit;
1020
1021 if (send_recovery) {
1022 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1023 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001024
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001025 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welteeded9ad2018-02-17 20:57:34 +01001026 apars.apn, apars.pco));
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001027 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1028 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1029 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1030 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1031 apars.sgsn_tei_c, apars.gtp_resp_cause,
1032 apars.ggsn_tei_c, apars.ggsn_tei_u,
1033 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001034 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1035 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001036 }
1037 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001038 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001039 setverdict(pass);
1040 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001041 [exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001042 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001043 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001044 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001045 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_REJ(apars.tid, ?))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001046 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001047 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001048 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001049 [not exp_rej] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi))) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001050 setverdict(pass);
1051 }
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001052 [] as_xid(apars);
Harald Welteeded9ad2018-02-17 20:57:34 +01001053 }
1054}
1055
Harald Welte6f203162018-02-18 22:04:55 +01001056function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause) runs on BSSGP_ConnHdlr {
1057 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1058 var Gtp1cUnitdata g_ud;
1059
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001060 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit));
Harald Welte6f203162018-02-18 22:04:55 +01001061 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1062 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001063 BSSGP[0].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001064 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1065 }
1066 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001067 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid))) {
Harald Welte6f203162018-02-18 22:04:55 +01001068 setverdict(pass);
1069 }
1070 [] as_xid(apars);
1071 }
1072}
1073
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001074function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false) runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001075 var Gtp1cUnitdata g_ud;
1076 var integer seq_nr := 23;
1077 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1078
Alexander Couzens0e510e62018-07-28 23:06:00 +02001079 BSSGP[0].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001080 if (error_ind) {
1081 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1082 } else {
1083 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1084 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001085
1086 timer T := 5.0;
1087 T.start;
1088
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001089 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001090 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001091 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Harald Welte57b9b7f2018-02-18 22:28:13 +01001092 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001093 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1094 repeat;
1095 }
1096 [] T.timeout {
1097 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1098 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001099 }
1100}
1101
Harald Welte6f203162018-02-18 22:04:55 +01001102
Harald Welteeded9ad2018-02-17 20:57:34 +01001103/* Table 10.5.156/3GPP TS 24.008 */
1104template (value) QoSV t_QosDefault := {
1105 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1106 delayClass := '100'B, /* best effort */
1107 spare1 := '00'B,
1108 precedenceClass := '010'B, /* normal */
1109 spare2 := '0'B,
1110 peakThroughput := '0000'B, /* subscribed */
1111 meanThroughput := '00000'B, /* subscribed */
1112 spare3 := '000'B,
1113 deliverErroneusSDU := omit,
1114 deliveryOrder := omit,
1115 trafficClass := omit,
1116 maxSDUSize := omit,
1117 maxBitrateUplink := omit,
1118 maxBitrateDownlink := omit,
1119 sduErrorRatio := omit,
1120 residualBER := omit,
1121 trafficHandlingPriority := omit,
1122 transferDelay := omit,
1123 guaranteedBitRateUplink := omit,
1124 guaranteedBitRateDownlink := omit,
1125 sourceStatisticsDescriptor := omit,
1126 signallingIndication := omit,
1127 spare4 := omit,
1128 maxBitrateDownlinkExt := omit,
1129 guaranteedBitRateDownlinkExt := omit,
1130 maxBitrateUplinkExt := omit,
1131 guaranteedBitRateUplinkExt := omit,
1132 maxBitrateDownlinkExt2 := omit,
1133 guaranteedBitRateDownlinkExt2 := omit,
1134 maxBitrateUplinkExt2 := omit,
1135 guaranteedBitRateUplinkExt2 := omit
1136}
1137
1138/* 10.5.6.4 / 3GPP TS 24.008 */
1139template (value) PDPAddressV t_AddrIPv4dyn := {
1140 pdpTypeOrg := '0001'B, /* IETF */
1141 spare := '0000'B,
1142 pdpTypeNum := '21'O, /* IPv4 */
1143 addressInfo := omit
1144}
1145template (value) PDPAddressV t_AddrIPv6dyn := {
1146 pdpTypeOrg := '0001'B, /* IETF */
1147 spare := '0000'B,
1148 pdpTypeNum := '53'O, /* IPv6 */
1149 addressInfo := omit
1150}
1151
Harald Welte37692d82018-02-18 15:21:34 +01001152template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001153 tid := '000'B,
1154 nsapi := '0101'B, /* < 5 are reserved */
1155 sapi := '0011'B, /* 3/5/9/11 */
1156 qos := t_QosDefault,
1157 addr := t_AddrIPv4dyn,
1158 apn := omit,
1159 pco := omit,
1160 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001161 gtp_resp_cause := int2oct(128, 1),
1162 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001163
1164 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001165 ggsn_tei_c := f_rnd_octstring(4),
1166 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001167 ggsn_ip_c := f_inet_addr(ggsn_ip),
1168 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001169 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001170
Harald Welteeded9ad2018-02-17 20:57:34 +01001171 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001172 sgsn_tei_u := omit,
1173 sgsn_ip_c := omit,
1174 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001175}
1176
Harald Welte37692d82018-02-18 15:21:34 +01001177template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1178 connId := 1,
1179 remName := f_inet_ntoa(ip),
1180 remPort := GTP1U_PORT
1181}
1182
1183template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1184 connId := 1,
1185 remName := f_inet_ntoa(ip),
1186 remPort := GTP1C_PORT
1187}
1188
1189private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1190 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1191 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1192}
1193
1194private altstep as_xid(PdpActPars apars) runs on BSSGP_ConnHdlr {
Harald Welte2aaac1b2019-05-02 10:02:53 +02001195 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID_MT_CMD(?, apars.sapi))) {
Harald Welte37692d82018-02-18 15:21:34 +01001196 repeat;
1197 }
1198}
1199
1200template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1201 pDU_SN_UNITDATA := {
1202 nsapi := nsapi,
1203 moreBit := ?,
1204 snPduType := '1'B,
1205 firstSegmentIndicator := ?,
1206 spareBit := ?,
1207 pcomp := ?,
1208 dcomp := ?,
1209 npduNumber := ?,
1210 segmentNumber := ?,
1211 npduNumberContinued := ?,
1212 dataSegmentSnUnitdataPdu := payload
1213 }
1214}
1215
1216/* simple case: single segment, no compression */
1217template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1218 pDU_SN_UNITDATA := {
1219 nsapi := nsapi,
1220 moreBit := '0'B,
1221 snPduType := '1'B,
1222 firstSegmentIndicator := '1'B,
1223 spareBit := '0'B,
1224 pcomp := '0000'B,
1225 dcomp := '0000'B,
1226 npduNumber := '0000'B,
1227 segmentNumber := '0000'B,
1228 npduNumberContinued := '00'O,
1229 dataSegmentSnUnitdataPdu := payload
1230 }
1231}
1232
1233/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
1234private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1235 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1236 f_gtpu_send(apars, payload);
1237 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1238 alt {
1239 [] as_xid(apars);
Alexander Couzens0e510e62018-07-28 23:06:00 +02001240 [] BSSGP[0].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Welte37692d82018-02-18 15:21:34 +01001241 }
1242}
1243
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001244/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Welte37692d82018-02-18 15:21:34 +01001245private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1246 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1247 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1248 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzens0e510e62018-07-28 23:06:00 +02001249 BSSGP[0].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001250 /* Expect PDU via GTP from SGSN on simulated GGSN */
1251 alt {
1252 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1253 }
1254}
1255
Harald Welteeded9ad2018-02-17 20:57:34 +01001256private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001257 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001258
1259 /* first perform regular attach */
1260 f_TC_attach(id);
1261
1262 f_pdp_ctx_act(apars);
1263}
1264testcase TC_attach_pdp_act() runs on test_CT {
1265 var BSSGP_ConnHdlr vc_conn;
1266 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001267 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001268 vc_conn.done;
1269}
Harald Welteb2124b22018-02-16 22:26:56 +01001270
Harald Welte835b15f2018-02-18 14:39:11 +01001271/* PDP Context activation for not-attached subscriber; expect fail */
1272private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001273 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001274 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001275 apars.apn, apars.pco));
1276 alt {
1277 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001278 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001279 setverdict(pass);
1280 }
1281 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1282 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001283 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001284 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001285 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_ACT_PDP_ACCEPT(?, ?))) {
Harald Welte835b15f2018-02-18 14:39:11 +01001286 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001287 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001288 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001289 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001290 }
1291}
1292testcase TC_pdp_act_unattached() runs on test_CT {
1293 var BSSGP_ConnHdlr vc_conn;
1294 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001295 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001296 vc_conn.done;
1297}
1298
Harald Welte37692d82018-02-18 15:21:34 +01001299/* ATTACH + PDP CTX ACT + user plane traffic */
1300private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1301 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1302
1303 /* first perform regular attach */
1304 f_TC_attach(id);
1305 /* then activate PDP context */
1306 f_pdp_ctx_act(apars);
1307 /* then transceive a downlink PDU */
1308 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1309 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1310}
1311testcase TC_attach_pdp_act_user() runs on test_CT {
1312 var BSSGP_ConnHdlr vc_conn;
1313 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001314 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001315 vc_conn.done;
1316}
1317
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001318/* ATTACH + PDP CTX ACT; reject from GGSN */
1319private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1320 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1321
1322 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1323 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1324
1325 /* first perform regular attach */
1326 f_TC_attach(id);
1327 /* then activate PDP context */
1328 f_pdp_ctx_act(apars);
1329}
1330testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1331 var BSSGP_ConnHdlr vc_conn;
1332 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001333 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001334 vc_conn.done;
1335}
Harald Welte835b15f2018-02-18 14:39:11 +01001336
Harald Welte6f203162018-02-18 22:04:55 +01001337/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1338private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1339 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1340
1341 /* first perform regular attach */
1342 f_TC_attach(id);
1343 /* then activate PDP context */
1344 f_pdp_ctx_act(apars);
1345 /* then transceive a downlink PDU */
1346 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1347 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1348
1349 f_pdp_ctx_deact_mo(apars, '00'O);
1350}
1351testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1352 var BSSGP_ConnHdlr vc_conn;
1353 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001354 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb, 21);
Harald Welte6f203162018-02-18 22:04:55 +01001355 vc_conn.done;
1356}
1357
Harald Welte57b9b7f2018-02-18 22:28:13 +01001358/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1359private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1360 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1361
1362 /* first perform regular attach */
1363 f_TC_attach(id);
1364 /* then activate PDP context */
1365 f_pdp_ctx_act(apars);
1366 /* then transceive a downlink PDU */
1367 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1368 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1369
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001370 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001371}
1372testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1373 var BSSGP_ConnHdlr vc_conn;
1374 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001375 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb, 22);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001376 vc_conn.done;
1377}
1378
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001379/* ATTACH + ATTACH (2nd) */
1380private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1381 g_pars.t_guard := 5.0;
1382
1383 /* first perform regular attach */
1384 f_TC_attach(id);
1385
1386 /* second to perform regular attach */
1387 f_TC_attach(id);
1388}
1389
1390
1391testcase TC_attach_second_attempt() runs on test_CT {
1392 var BSSGP_ConnHdlr vc_conn;
1393 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001394 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001395 vc_conn.done;
1396}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001397
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001398private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001399 var Gtp1cUnitdata g_ud;
1400 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1401
1402 /* first perform regular attach */
1403 f_TC_attach(id);
1404 /* Activate a pdp context against the GGSN */
1405 f_pdp_ctx_act(apars);
1406 /* Wait to receive first echo request and send initial Restart counter */
1407 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1408 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1409 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1410 }
1411 /* Wait to receive second echo request and send incremented Restart
1412 counter. This will fake a restarted GGSN, and pdp ctx allocated
1413 should be released by SGSN */
1414 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1415 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1416 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1417 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1418 }
1419 var OCT1 cause_network_failure := int2oct(38, 1)
1420 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001421 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true))) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001422 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001423 setverdict(pass);
1424 }
1425 [] as_xid(apars);
1426 }
1427 setverdict(pass);
1428}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001429/* ATTACH + trigger Recovery procedure through EchoResp */
1430testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001431 var BSSGP_ConnHdlr vc_conn;
1432 g_use_echo := true
1433 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001434 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_echo), testcasename(), g_gb, 23, 30.0);
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001435 vc_conn.done;
1436 g_use_echo := false
1437}
1438
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001439private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1440 var Gtp1cUnitdata g_ud;
1441 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1442 var integer seq_nr := 23;
1443 var GtpPeer peer;
1444 /* first perform regular attach */
1445 f_TC_attach(id);
1446
1447 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1448 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1449 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1450 f_pdp_ctx_act(apars, true);
1451
1452 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1453/* received. */
1454 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1455
1456 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1457 would be great to have an active pdp context here before triggering
1458 Recovery, and making sure the the DEACT request is sent by the SGSN.
1459 */
1460
1461 /* Activate a pdp context against the GGSN, send incremented Recovery
1462 IE. This should trigger the recovery path, but still this specific
1463 CTX activation should work. */
1464 apars.exp_rej_cause := omit; /* default value for tests */
1465 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1466 f_pdp_ctx_act(apars, true);
1467
1468 setverdict(pass);
1469}
1470/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1471testcase TC_attach_restart_ctr_create() runs on test_CT {
1472 var BSSGP_ConnHdlr vc_conn;
1473 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001474 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb, 24, 30.0);
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001475 vc_conn.done;
1476}
1477
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001478/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1479private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1480 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1481 var integer seq_nr := 23;
1482 var GtpPeer peer;
1483 var integer i;
1484
1485 /* first perform regular attach */
1486 f_TC_attach(id);
1487 /* then activate PDP context */
1488 f_pdp_ctx_act(apars);
1489
Alexander Couzens0e510e62018-07-28 23:06:00 +02001490 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001491 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1492 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1493
1494 for (i := 0; i < 5; i := i+1) {
1495 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001496 [] BSSGP[0].receive(tr_BD_L3_MT(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true))) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001497 [] as_xid(apars);
1498 }
1499 }
1500
1501 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1502
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001503 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001504 setverdict(pass);
1505}
1506testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1507 var BSSGP_ConnHdlr vc_conn;
1508 f_init();
1509 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001510 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb, 25, 60.0);
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001511 vc_conn.done;
1512}
1513
Alexander Couzens5e307b42018-05-22 18:12:20 +02001514private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1515 /* MS: perform regular attach */
1516 f_TC_attach(id);
1517
1518 /* HLR: cancel the location request */
1519 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1520 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001521
1522 /* ensure no Detach Request got received */
1523 timer T := 5.0;
1524 T.start;
1525 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001526 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(*, *, *))) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001527 T.stop;
1528 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001529 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001530 }
1531 [] T.timeout {
1532 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001533 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001534 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001535 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001536 repeat;
1537 }
1538 }
1539}
1540
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001541/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1542private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1543 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1544
1545 /* first perform regular attach */
1546 f_TC_attach(id);
1547 /* then activate PDP context */
1548 f_pdp_ctx_act(apars);
1549 /* then transceive a downlink PDU */
1550 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1551
1552 /* Send Error indication as response from upload PDU and expect deact towards MS */
1553 f_pdp_ctx_deact_mt(apars, true);
1554}
1555testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1556 var BSSGP_ConnHdlr vc_conn;
1557 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001558 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb, 26);
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001559 vc_conn.done;
1560}
1561
Alexander Couzens5e307b42018-05-22 18:12:20 +02001562testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1563 /* MS <-> SGSN: GMM Attach
1564 * HLR -> SGSN: Cancel Location Request
1565 * HLR <- SGSN: Cancel Location Ack
1566 */
1567 var BSSGP_ConnHdlr vc_conn;
1568 f_init();
1569 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001570 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001571 vc_conn.done;
1572}
1573
1574
Alexander Couzensc87967a2018-05-22 16:09:54 +02001575private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1576 /* MS: perform regular attach */
1577 f_TC_attach(id);
1578
1579 /* HLR: cancel the location request */
1580 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1581 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1582 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1583
1584 /* MS: receive a Detach Request */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001585 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?)));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001586 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001587
1588 setverdict(pass);
1589}
1590
1591testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1592 /* MS <-> SGSN: GMM Attach
1593 * HLR -> SGSN: Cancel Location Request
1594 * HLR <- SGSN: Cancel Location Ack
1595 * MS <- SGSN: Detach Request
1596 * SGSN-> MS: Detach Complete
1597 */
1598 var BSSGP_ConnHdlr vc_conn;
1599 f_init();
1600 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001601 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001602 vc_conn.done;
1603}
1604
1605
Alexander Couzens6c47f292018-05-22 17:09:49 +02001606private function f_hlr_location_cancel_request_unknown_subscriber(
1607 charstring id,
1608 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1609
1610 /* HLR: cancel the location request */
1611 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1612
1613 /* cause 2 = IMSI_UNKNOWN */
1614 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1615
1616 setverdict(pass);
1617}
1618
1619private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001620 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001621}
1622
1623testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1624 /* HLR -> SGSN: Cancel Location Request
1625 * HLR <- SGSN: Cancel Location Error
1626 */
1627
1628 var BSSGP_ConnHdlr vc_conn;
1629 f_init();
1630 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001631 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001632 vc_conn.done;
1633}
1634
1635private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001636 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001637}
1638
1639testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1640 /* HLR -> SGSN: Cancel Location Request
1641 * HLR <- SGSN: Cancel Location Error
1642 */
1643
1644 var BSSGP_ConnHdlr vc_conn;
1645 f_init();
1646 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001647 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001648 vc_conn.done;
1649}
1650
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001651private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1652 f_TC_attach(id);
1653 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1654}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001655
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001656testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1657 /* MS <-> SGSN: Attach
1658 * MS -> SGSN: Detach Req (Power off)
1659 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1660 */
1661 var BSSGP_ConnHdlr vc_conn;
1662 var integer id := 33;
1663 var charstring imsi := hex2str(f_gen_imsi(id));
1664
1665 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001666 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001667 vc_conn.done;
1668
1669 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1670}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001671
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001672/* Attempt an attach, but loose the Identification Request (IMEI) */
1673private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1674 var integer count_req := 0;
1675 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1676
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001677 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001678
1679 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001680 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001681 /* break */
1682 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001683 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001684 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001685 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001686 repeat;
1687 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001688 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001689 /* ignore ID REQ IMEI */
1690 count_req := count_req + 1;
1691 repeat;
1692 }
1693 }
1694 if (count_req != 5) {
1695 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001696 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001697 }
1698 setverdict(pass);
1699}
1700
1701testcase TC_attach_no_imei_response() runs on test_CT {
1702 /* MS -> SGSN: Attach Request IMSI
1703 * MS <- SGSN: Identity Request IMSI (optional)
1704 * MS -> SGSN: Identity Response IMSI (optional)
1705 * MS <- SGSN: Identity Request IMEI
1706 * MS -x SGSN: no response
1707 * MS <- SGSN: re-send: Identity Request IMEI 4x
1708 * MS <- SGSN: Attach Reject
1709 */
1710 var BSSGP_ConnHdlr vc_conn;
1711 f_init();
1712 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001713 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb, 32, 60.0);
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001714 vc_conn.done;
1715}
1716
Alexander Couzens53f20562018-06-12 16:24:12 +02001717/* Attempt an attach, but loose the Identification Request (IMSI) */
1718private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1719 var integer count_req := 0;
1720 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1721
1722 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1723 g_pars.p_tmsi := 'c0000035'O;
1724
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001725 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02001726
1727 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001728 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001729 /* break */
1730 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001731 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001732 /* ignore ID REQ IMSI */
1733 count_req := count_req + 1;
1734 repeat;
1735 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001736 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001737 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001738 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001739 repeat;
1740 }
1741 }
1742 if (count_req != 5) {
1743 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001744 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001745 }
1746 setverdict(pass);
1747}
1748
1749testcase TC_attach_no_imsi_response() runs on test_CT {
1750 /* MS -> SGSN: Attach Request TMSI (unknown)
1751 * MS <- SGSN: Identity Request IMEI (optional)
1752 * MS -> SGSN: Identity Response IMEI (optional)
1753 * MS <- SGSN: Identity Request IMSI
1754 * MS -x SGSN: no response
1755 * MS <- SGSN: re-send: Identity Request IMSI 4x
1756 * MS <- SGSN: Attach Reject
1757 */
1758 var BSSGP_ConnHdlr vc_conn;
1759 f_init();
1760 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001761 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb, 35, 60.0);
Alexander Couzens53f20562018-06-12 16:24:12 +02001762 vc_conn.done;
1763}
1764
Alexander Couzenscf818962018-06-05 18:00:00 +02001765private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1766 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1767}
1768
1769testcase TC_attach_check_subscriber_list() runs on test_CT {
1770 /* MS <-> SGSN: Attach
1771 * VTY -> SGSN: Check if MS is in subscriber cache
1772 */
1773 var BSSGP_ConnHdlr vc_conn;
1774 var integer id := 34;
1775 var charstring imsi := hex2str(f_gen_imsi(id));
1776
1777 f_init();
1778 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001779 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001780 vc_conn.done;
1781
1782 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1783 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1784}
1785
Alexander Couzensf9858652018-06-07 16:14:53 +02001786private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1787 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1788 var BssgpDecoded bd;
1789
1790 /* unregister the old IMSI */
1791 f_bssgp_client_unregister(g_pars.imsi);
1792 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02001793 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001794 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02001795
1796 /* there is no auth */
1797 g_pars.net.expect_auth := false;
1798
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001799 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02001800 f_gmm_auth();
1801 alt {
Alexander Couzens0e510e62018-07-28 23:06:00 +02001802 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
Alexander Couzensf9858652018-06-07 16:14:53 +02001803 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001804 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02001805 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001806 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) -> value bd {
Alexander Couzensf9858652018-06-07 16:14:53 +02001807 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001808 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02001809 setverdict(pass);
1810 }
1811 }
1812}
Alexander Couzens03d12242018-08-07 16:13:52 +02001813
1814private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
1815
1816 f_TC_attach_closed_foreign(id);
1817 f_TC_attach_closed_imsi_added(id);
1818
1819}
1820
1821
Alexander Couzensf9858652018-06-07 16:14:53 +02001822testcase TC_attach_closed_add_vty() runs on test_CT {
1823 /* VTY-> SGSN: policy close
1824 * MS -> SGSN: Attach Request
1825 * MS <- SGSN: Identity Request IMSI
1826 * MS -> SGSN: Identity Response IMSI
1827 * MS <- SGSN: Attach Reject
1828 * VTY-> SGSN: policy imsi-acl add IMSI
1829 * MS -> SGSN: Attach Request
1830 * MS <- SGSN: Identity Request IMSI
1831 * MS -> SGSN: Identity Response IMSI
1832 * MS <- SGSN: Identity Request IMEI
1833 * MS -> SGSN: Identity Response IMEI
1834 * MS <- SGSN: Attach Accept
1835 */
1836 var BSSGP_ConnHdlr vc_conn;
1837 f_init();
1838 f_sleep(1.0);
1839 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1840 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02001841 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
1842 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02001843 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02001844 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02001845 vc_conn.done;
1846}
1847
Alexander Couzens0085bd72018-06-12 19:08:44 +02001848/* Attempt an attach, but never answer a Attach Complete */
1849private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
1850 var integer count_req := 0;
1851
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001852 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02001853 f_gmm_auth();
1854
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001855 timer T := 10.0;
1856 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001857 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001858 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001859 /* break */
1860 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001861 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(*, *, *))) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02001862 /* ignore */
1863 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02001864 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001865 repeat;
1866 }
1867 }
1868 if (count_req != 5) {
1869 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02001870 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02001871 }
1872 setverdict(pass);
1873}
1874
1875testcase TC_attach_check_complete_resend() runs on test_CT {
1876 /* MS -> SGSN: Attach Request IMSI
1877 * MS <- SGSN: Identity Request *
1878 * MS -> SGSN: Identity Response *
1879 * MS <- SGSN: Attach Complete 5x
1880 */
1881 var BSSGP_ConnHdlr vc_conn;
1882 f_init();
1883 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001884 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb, 36, 60.0);
Alexander Couzens0085bd72018-06-12 19:08:44 +02001885 vc_conn.done;
1886}
1887
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001888private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
1889 var BssgpDecoded bd;
1890
1891 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001892 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit), bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001893 alt {
1894 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_ACCEPT)) -> value bd {
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001895 f_process_rau_accept(bd.l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001896 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001897 setverdict(pass);
1898 }
1899 [] BSSGP[bssgp].receive(tr_BD_L3_MT(tr_GMM_RAU_REJECT)) {
1900 setverdict(fail, "Unexpected RAU Reject");
1901 mtc.stop;
1902 }
1903 [] BSSGP[bssgp].receive { repeat; }
1904 }
1905}
1906
Alexander Couzensbfda9212018-07-31 03:17:33 +02001907private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
1908 var BssgpDecoded bd;
1909
1910 /* first perform regular attach */
1911 f_TC_attach(id);
1912
1913 /* then send RAU */
1914 f_routing_area_update(g_pars.ra);
1915
1916 /* do another RAU */
1917 f_routing_area_update(g_pars.ra);
1918
1919 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1920}
1921
1922testcase TC_attach_rau_a_a() runs on test_CT {
1923 /* MS <-> SGSN: Successful Attach
1924 * MS -> SGSN: Routing Area Update Request
1925 * MS <- SGSN: Routing Area Update Accept
1926 * MS -> SGSN: Routing Area Update Request
1927 * MS <- SGSN: Routing Area Update Accept
1928 * MS -> SGSN: Detach (PowerOff)
1929 */
1930 var BSSGP_ConnHdlr vc_conn;
1931 f_init();
1932 f_sleep(1.0);
1933 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
1934 vc_conn.done;
1935}
1936
Alexander Couzensbe837bd2018-07-31 04:20:11 +02001937private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
1938 var BssgpDecoded bd;
1939
1940 f_TC_attach(id);
1941
1942 log("attach complete sending rau");
1943 f_routing_area_update(g_pars.ra, 0);
1944
1945 log("rau complete unregistering");
1946 f_bssgp_client_unregister(g_pars.imsi);
1947 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
1948
1949 log("sending second RAU via different RA");
1950 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
1951
1952 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
1953}
1954
1955testcase TC_attach_rau_a_b() runs on test_CT {
1956 /* MS <-> SGSN: Successful Attach
1957 * MS -> SGSN: Routing Area _a_ Update Request
1958 * MS <- SGSN: Routing Area _a_ Update Accept
1959 * MS -> SGSN: Routing Area _b_ Update Request
1960 * MS <- SGSN: Routing Area _b_ Update Accept
1961 * MS -> SGSN: Detach (PowerOff)
1962 */
1963 var BSSGP_ConnHdlr vc_conn;
1964 f_init();
1965 f_sleep(1.0);
1966 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
1967 vc_conn.done;
1968}
1969
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02001970private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
1971 var integer count_req := 0;
1972 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1973 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
1974 var BssgpDecoded bd;
1975
1976 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1977
1978 alt {
1979 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
1980 setverdict(fail, "Unexpected GMM ATTACH REJECT");
1981 mtc.stop;
1982 }
1983 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
1984 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1985 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1986 repeat;
1987 }
1988 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
1989 /* send out a second GMM_Attach Request.
1990 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
1991 * of the same content */
1992 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
1993 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
1994 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
1995 }
1996 }
1997 f_sleep(1.0);
1998
1999 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2000 alt {
2001 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
2002 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2003 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2004 repeat;
2005 }
2006 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
2007 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2008 mtc.stop;
2009 }
2010 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_REJECT(?))) {
2011 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2012 mtc.stop;
2013 }
2014 [] BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2015 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2016 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2017 setverdict(pass);
2018 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2019 }
2020 }
2021}
2022
2023testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2024 /* Testing if the SGSN ignore Attach Request with the exact same content */
2025 /* MS -> SGSN: Attach Request IMSI
2026 * MS <- SGSN: Identity Request IMSI (optional)
2027 * MS -> SGSN: Identity Response IMSI (optional)
2028 * MS <- SGSN: Identity Request IMEI
2029 * MS -> SGSN: Attach Request (2nd)
2030 * MS <- SGSN: Identity Response IMEI
2031 * MS <- SGSN: Attach Accept
2032 * MS -> SGSN: Attach Complete
2033 */
2034 var BSSGP_ConnHdlr vc_conn;
2035 f_init();
2036 f_sleep(1.0);
2037 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2038 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2039 vc_conn.done;
2040}
2041
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002042private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
2043 var BssgpDecoded bd;
2044 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2045
2046 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2047
2048 /* send Attach Request */
2049 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2050 * 3G auth vectors */
2051 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2052 /* The thing is, if the solSACapability is 'omit', then the
2053 * revisionLevelIndicatior is at the wrong place! */
2054 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2055 f_send_l3_gmm_llc(attach_req);
2056
2057 /* do the auth */
2058 var PDU_L3_MS_SGSN l3_mo;
2059 var PDU_L3_SGSN_MS l3_mt;
2060 var default di := activate(as_mm_identity());
2061
2062 var GSUP_IE auth_tuple;
2063 var template AuthenticationParameterAUTNTLV autn;
2064
2065 g_pars.vec := f_gen_auth_vec_3g();
2066 autn := {
2067 elementIdentifier := '28'O,
2068 lengthIndicator := lengthof(g_pars.vec.autn),
2069 autnValue := g_pars.vec.autn
2070 };
2071 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2072 g_pars.vec.sres,
2073 g_pars.vec.kc,
2074 g_pars.vec.ik,
2075 g_pars.vec.ck,
2076 g_pars.vec.autn,
2077 g_pars.vec.res));
2078 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2079 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2080 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2081
2082 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2083 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2084 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2085
2086 /* send the gmm auth failure with resync IE */
2087 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2088
2089 /* wait for the GSUP resync request */
2090 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2091 g_pars.imsi,
2092 g_pars.vec.auts,
2093 g_pars.vec.rand));
2094
2095 /* generate new key material */
2096 g_pars.vec := f_gen_auth_vec_3g();
2097 autn := {
2098 elementIdentifier := '28'O,
2099 lengthIndicator := lengthof(g_pars.vec.autn),
2100 autnValue := g_pars.vec.autn
2101 };
2102
2103 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2104 g_pars.vec.sres,
2105 g_pars.vec.kc,
2106 g_pars.vec.ik,
2107 g_pars.vec.ck,
2108 g_pars.vec.autn,
2109 g_pars.vec.res));
2110 /* send new key material */
2111 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2112
2113 /* wait for the new Auth Request */
2114 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2115 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
2116 BSSGP[0].receive(tr_BD_L3_MT(auth_ciph_req)) -> value bd;
2117 l3_mt := bd.l3_mt;
2118 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2119 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2120 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2121 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2122 valueField := substr(g_pars.vec.res, 0, 4)
2123 };
2124 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2125 elementIdentifier := '21'O,
2126 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2127 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2128 };
2129 l3_mo := valueof(auth_ciph_resp);
2130 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2131 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2132 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2133 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2134 }
2135 f_send_l3_gmm_llc(l3_mo);
2136 deactivate(di);
2137
2138 /* Expect SGSN to perform LU with HLR */
2139 f_gmm_gsup_lu_isd();
2140
2141 BSSGP[0].receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?))) -> value bd {
2142 f_process_attach_accept(bd.l3_mt.msgs.gprs_mm.attachAccept);
2143 }
2144 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2145 setverdict(pass);
2146}
2147
2148testcase TC_attach_usim_resync() runs on test_CT {
2149 /* MS -> SGSN: Attach Request
2150 * MS <- SGSN: Identity Request IMSI
2151 * MS -> SGSN: Identity Response IMSI
2152 * MS <- SGSN: Identity Request IMEI
2153 * MS -> SGSN: Identity Response IMEI
2154 * HLR<- SGSN: SAI Request
2155 * HLR-> SGSN: SAI Response
2156 * MS <- SGSN: Auth Request
2157 * MS -> SGSN: Auth Failure (with AUTS)
2158 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2159 * HLR-> SGSN: SAI Response (new key material)
2160 * MS <- SGSN: Auth Request (new key material)
2161 * MS -> SGSN: Auth Response
2162 * MS <- SGSN: Attach Accept
2163 * MS -> SGSN: Attach Complete
2164 */
2165 var BSSGP_ConnHdlr vc_conn;
2166 f_init();
2167 f_sleep(1.0);
2168 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2169 vc_conn.done;
2170}
2171
Harald Weltea05b8072019-04-23 22:35:05 +02002172
2173/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2174private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2175 f_gmm_attach(false, false);
2176 f_sleep(1.0);
2177 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2178 /* try to detach to check if SGSN is still alive */
2179 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2180}
2181testcase TC_llc_null() runs on test_CT {
2182 var BSSGP_ConnHdlr vc_conn;
2183 f_init();
2184 f_sleep(1.0);
2185 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2186 vc_conn.done;
2187}
2188
Harald Welte645a1512019-04-23 23:18:23 +02002189/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2190private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2191 f_gmm_attach(false, false);
2192 f_sleep(1.0);
2193 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2194 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP)));
2195 setverdict(pass);
2196}
2197testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2198 var BSSGP_ConnHdlr vc_conn;
2199 f_init();
2200 f_sleep(1.0);
2201 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2202 vc_conn.done;
2203}
2204
2205/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2206private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2207 f_gmm_attach(false, false);
2208 f_sleep(1.0);
2209 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
2210 BSSGP[0].receive(tr_BD_LLC(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP)));
2211 setverdict(pass);
2212}
2213testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2214 var BSSGP_ConnHdlr vc_conn;
2215 f_init();
2216 f_sleep(1.0);
2217 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2218 vc_conn.done;
2219}
2220
Harald Welte2aaac1b2019-05-02 10:02:53 +02002221/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2222private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2223 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2224 var template (value) XID_Information xid;
2225 var template XID_Information xid_rx;
2226
2227 /* first perform regular attach */
2228 f_TC_attach(id);
2229 /* then activate PDP context */
2230 f_pdp_ctx_act(apars);
2231
2232 /* start MO XID */
2233 xid := { ts_XID_L3(''O) };
2234 xid_rx := { tr_XID_L3(''O) };
2235 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2236 alt {
2237 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID(xid_rx, apars.sapi)));
2238 [] as_xid(apars);
2239 }
2240 setverdict(pass);
2241}
2242testcase TC_xid_empty_l3() runs on test_CT {
2243 var BSSGP_ConnHdlr vc_conn;
2244 f_init();
2245 f_sleep(1.0);
2246 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2247 vc_conn.done;
2248}
2249
2250private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2251 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2252 var template (value) XID_Information xid;
2253 var template XID_Information xid_rx;
2254
2255 /* first perform regular attach */
2256 f_TC_attach(id);
2257 /* then activate PDP context */
2258 f_pdp_ctx_act(apars);
2259
2260 /* start MO XID */
2261 xid := { ts_XID_N201U(1234) };
2262 xid_rx := { tr_XID_N201U(1234) };
2263 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2264 alt {
2265 [] BSSGP[0].receive(tr_BD_LLC(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi)));
2266 [] as_xid(apars);
2267 }
2268 setverdict(pass);
2269}
2270testcase TC_xid_n201u() runs on test_CT {
2271 var BSSGP_ConnHdlr vc_conn;
2272 f_init();
2273 f_sleep(1.0);
2274 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2275 vc_conn.done;
2276}
2277
Harald Welte645a1512019-04-23 23:18:23 +02002278
2279
Harald Welte5ac31492018-02-15 20:39:13 +01002280control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002281 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002282 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002283 execute( TC_attach_umts_aka_umts_res() );
2284 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002285 execute( TC_attach_auth_id_timeout() );
2286 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002287 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002288 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002289 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002290 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002291 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002292 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002293 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002294 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002295 execute( TC_attach_closed_add_vty(), 20.0 );
2296 execute( TC_attach_check_subscriber_list(), 20.0 );
2297 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002298 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002299 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2300 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2301 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2302 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002303 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002304 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002305 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002306 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002307 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002308 execute( TC_detach_unknown_nopoweroff() );
2309 execute( TC_detach_unknown_poweroff() );
2310 execute( TC_detach_nopoweroff() );
2311 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002312 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002313 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002314 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002315 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002316 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002317 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002318 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002319 execute( TC_attach_restart_ctr_echo() );
2320 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002321 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002322 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002323 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002324
Harald Welte2aaac1b2019-05-02 10:02:53 +02002325 execute( TC_xid_empty_l3() );
2326 execute( TC_xid_n201u() );
2327
Harald Weltea05b8072019-04-23 22:35:05 +02002328 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002329 execute( TC_llc_sabm_dm_llgmm() );
2330 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002331}
Harald Welte96a33b02018-02-04 10:36:22 +01002332
2333
2334
2335}