blob: a326a834c673bdf1af01fe03da04cf3abe3c41ce [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
3import from General_Types all;
4import from Osmocom_Types all;
5import from NS_Types all;
6import from NS_Emulation all;
7import from BSSGP_Types all;
8import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +01009import from Osmocom_Gb_Types all;
10
11import from MobileL3_CommonIE_Types all;
12import from MobileL3_GMM_SM_Types all;
13import from MobileL3_Types all;
14import from L3_Templates all;
15import from L3_Common all;
16
17import from GSUP_Emulation all;
18import from GSUP_Types all;
19import from IPA_Emulation all;
20
21modulepar {
22 /* IP/port on which we run our internal GSUP/HLR emulation */
23 charstring mp_hlr_ip := "127.0.0.1";
24 integer mp_hlr_port := 4222;
25};
26
27type record GbInstance {
28 NS_CT vc_NS,
29 BSSGP_CT vc_BSSGP,
30 BssgpConfig cfg
31};
Harald Welte96a33b02018-02-04 10:36:22 +010032
33type component test_CT {
Harald Welte5ac31492018-02-15 20:39:13 +010034 var GbInstance g_gb[3];
Harald Welte96a33b02018-02-04 10:36:22 +010035
Harald Welte5ac31492018-02-15 20:39:13 +010036 var GSUP_Emulation_CT vc_GSUP;
37 var IPA_Emulation_CT vc_GSUP_IPA;
38 /* only to get events from IPA underneath GSUP */
39 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +010040
41 var boolean g_initialized := false;
42};
43
Harald Welte5ac31492018-02-15 20:39:13 +010044type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr {
45 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +010046 timer g_Tguard;
Harald Welte5ac31492018-02-15 20:39:13 +010047}
48
49type record SGSN_ConnHdlrNetworkPars {
50 boolean expect_ptmsi,
51 boolean expect_auth,
52 boolean expect_ciph
53};
54
55type record BSSGP_ConnHdlrPars {
56 /* IMEI of the simulated ME */
57 hexstring imei,
58 /* IMEI of the simulated MS */
59 hexstring imsi,
60 /* MSISDN of the simulated MS (probably unused) */
61 hexstring msisdn,
62 /* P-TMSI allocated to the simulated MS */
63 OCT4 p_tmsi optional,
64 /* TLLI of the simulated MS */
65 OCT4 tlli,
66 RoutingAreaIdentificationV ra optional,
67 BssgpCellId bssgp_cell_id,
68 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +010069 SGSN_ConnHdlrNetworkPars net,
70 float t_guard
Harald Welte5ac31492018-02-15 20:39:13 +010071};
72
73
74private function f_init_gb(inout GbInstance gb) runs on test_CT {
75 gb.vc_NS := NS_CT.create;
76 gb.vc_BSSGP := BSSGP_CT.create;
77 /* connect lower end of BSSGP emulation with NS upper port */
78 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
79 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
80 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
81
82 gb.vc_NS.start(NSStart());
83 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
84}
85
86private function f_init_gsup(charstring id) runs on test_CT {
87 id := id & "-GSUP";
88 var GsupOps ops := {
89 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
90 };
91
92 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
93 vc_GSUP := GSUP_Emulation_CT.create(id);
94
95 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
96 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
97 /* we use this hack to get events like ASP_IPA_EVENT_UP */
98 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
99
100 vc_GSUP.start(GSUP_Emulation.main(ops, id));
101 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
102
103 /* wait for incoming connection to GSUP port before proceeding */
104 timer T := 10.0;
105 T.start;
106 alt {
107 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
108 [] T.timeout {
109 setverdict(fail, "No connection to GSUP Port");
110 self.stop;
111 }
112 }
113}
114
Harald Welte96a33b02018-02-04 10:36:22 +0100115function f_init() runs on test_CT {
116 if (g_initialized == true) {
117 return;
118 }
119 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100120 g_gb[0].cfg := {
121 nsei := 96,
122 bvci := 196,
123 cell_id := {
124 ra_id := {
125 lai := {
126 mcc_mnc := '26242F'H, lac := 13135},
127 rac := 0
128 },
129 cell_id := 20960
130 },
131 sgsn_role := false
132 };
Harald Welte96a33b02018-02-04 10:36:22 +0100133
Harald Welte5ac31492018-02-15 20:39:13 +0100134 f_init_gb(g_gb[0]);
135 f_init_gsup("SGSN_Test");
136}
Harald Welte96a33b02018-02-04 10:36:22 +0100137
Harald Welte5ac31492018-02-15 20:39:13 +0100138type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
139
140/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte62e29582018-02-16 21:17:11 +0100141function f_start_handler(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix,
142 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100143runs on test_CT return BSSGP_ConnHdlr {
144 var BSSGP_ConnHdlr vc_conn;
145 var SGSN_ConnHdlrNetworkPars net_pars := {
146 expect_ptmsi := true,
147 expect_auth := true,
148 expect_ciph := false
149 };
150 var BSSGP_ConnHdlrPars pars := {
151 imei := f_gen_imei(imsi_suffix),
152 imsi := f_gen_imsi(imsi_suffix),
153 msisdn := f_gen_msisdn(imsi_suffix),
154 p_tmsi := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100155 tlli := f_gprs_tlli_random(),
Harald Welte5ac31492018-02-15 20:39:13 +0100156 ra := omit,
157 bssgp_cell_id := gb.cfg.cell_id,
158 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100159 net := net_pars,
160 t_guard := t_guard
Harald Welte5ac31492018-02-15 20:39:13 +0100161 };
162
163 vc_conn := BSSGP_ConnHdlr.create(id);
164 connect(vc_conn:BSSGP, gb.vc_BSSGP:BSSGP_SP);
165 connect(vc_conn:BSSGP_PROC, gb.vc_BSSGP:BSSGP_PROC);
166
167 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
168 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
169
170 vc_conn.start(f_handler_init(fn, id, pars));
171 return vc_conn;
172}
173
Harald Welte62e29582018-02-16 21:17:11 +0100174private altstep as_Tguard() runs on BSSGP_ConnHdlr {
175 [] g_Tguard.timeout {
176 setverdict(fail, "Tguard timeout");
177 self.stop;
178 }
179}
180
Harald Welte5ac31492018-02-15 20:39:13 +0100181/* first function called in every ConnHdlr */
182private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
183runs on BSSGP_ConnHdlr {
184 /* do some common stuff like setting up g_pars */
185 g_pars := pars;
186
187 /* register with BSSGP core */
188 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
189 /* tell GSUP dispatcher to send this IMSI to us */
190 f_create_gsup_expect(hex2str(g_pars.imsi));
191
Harald Welte62e29582018-02-16 21:17:11 +0100192 g_Tguard.start(pars.t_guard);
193 activate(as_Tguard());
194
Harald Welte5ac31492018-02-15 20:39:13 +0100195 /* call the user-supplied test case function */
196 fn.apply(id);
197 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100198}
199
200/* TODO:
201 * RAU without Attach
202 * Detach without Attach
203 * SM procedures without attach / RAU
204 * ATTACH / RAU
205 ** with / without authentication
206 ** with / without P-TMSI allocation
207 ** timeout from HLR on SAI
208 ** timeout from HLR on UL
209 ** reject from HLR on SAI
210 ** reject from HLR on UL
211 * re-transmissions of LLC frames
212 * PDP Context activation
213 ** with different GGSN config in SGSN VTY
214 ** with different PDP context type (v4/v6/v46)
215 ** timeout from GGSN
216 ** reject from GGSN
217 */
218
219testcase TC_wait_ns_up() runs on test_CT {
220 f_init();
221 f_sleep(20.0);
222}
223
Harald Welte5ac31492018-02-15 20:39:13 +0100224altstep as_mm_identity() runs on BSSGP_ConnHdlr {
225 var MobileIdentityLV mi;
226 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
227 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
228 BSSGP.send(ts_GMM_ID_RESP(mi));
229 repeat;
230 }
231 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
232 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
233 BSSGP.send(ts_GMM_ID_RESP(mi));
234 repeat;
235 }
236}
Harald Welte96a33b02018-02-04 10:36:22 +0100237
Harald Welte5ac31492018-02-15 20:39:13 +0100238function f_gmm_auth () runs on BSSGP_ConnHdlr {
239 var BssgpDecoded bd;
240 var PDU_L3_MS_SGSN l3_mo;
241 var PDU_L3_SGSN_MS l3_mt;
242 var default di := activate(as_mm_identity());
243 if (g_pars.net.expect_auth) {
244 g_pars.vec := f_gen_auth_vec_2g();
245 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
246 g_pars.vec.sres,
247 g_pars.vec.kc));
248 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
249 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
250 BSSGP.receive(tr_BD_L3_MT(tr_GMM_AUTH_REQ(g_pars.vec.rand))) -> value bd;
251 l3_mt := bd.l3_mt;
252 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
253 l3_mo := valueof(ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres));
254 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
255 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
256 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
257 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
258 }
259 BSSGP.send(l3_mo);
260 }
261 deactivate(di);
262}
263
Harald Welte5a4fa042018-02-16 20:59:21 +0100264function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
265 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
266}
267
Harald Welte5ac31492018-02-15 20:39:13 +0100268private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
269 var MobileIdentityLV mi;
Harald Welte5a4fa042018-02-16 20:59:21 +0100270 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte5ac31492018-02-15 20:39:13 +0100271
272 if (ispresent(g_pars.p_tmsi)) {
273 mi := valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
274 } else {
275 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
276 }
277
278 BSSGP.send(ts_GMM_ATTACH_REQ(mi, old_ra, false, false, omit, omit));
279 f_gmm_auth();
280 /* Expect MSC to perform LU with HLR */
281 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
282 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
283 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
284 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
285
286 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(?, ?, ?)));
287 BSSGP.send(ts_GMM_ATTACH_COMPL);
Harald Welte5a4fa042018-02-16 20:59:21 +0100288 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100289}
290
291testcase TC_attach() runs on test_CT {
292 var BSSGP_ConnHdlr vc_conn;
293 f_init();
294 f_sleep(1.0);
295 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1);
296 vc_conn.done;
297}
298
299
300control {
301 execute( TC_wait_ns_up() );
302}
Harald Welte96a33b02018-02-04 10:36:22 +0100303
304
305
306}