blob: cf354a761b4e0c16fa5af4a0e41c57064a872017 [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;
46}
47
48type record SGSN_ConnHdlrNetworkPars {
49 boolean expect_ptmsi,
50 boolean expect_auth,
51 boolean expect_ciph
52};
53
54type record BSSGP_ConnHdlrPars {
55 /* IMEI of the simulated ME */
56 hexstring imei,
57 /* IMEI of the simulated MS */
58 hexstring imsi,
59 /* MSISDN of the simulated MS (probably unused) */
60 hexstring msisdn,
61 /* P-TMSI allocated to the simulated MS */
62 OCT4 p_tmsi optional,
63 /* TLLI of the simulated MS */
64 OCT4 tlli,
65 RoutingAreaIdentificationV ra optional,
66 BssgpCellId bssgp_cell_id,
67 AuthVector vec optional,
68 SGSN_ConnHdlrNetworkPars net
69};
70
71
72private function f_init_gb(inout GbInstance gb) runs on test_CT {
73 gb.vc_NS := NS_CT.create;
74 gb.vc_BSSGP := BSSGP_CT.create;
75 /* connect lower end of BSSGP emulation with NS upper port */
76 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
77 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
78 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
79
80 gb.vc_NS.start(NSStart());
81 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
82}
83
84private function f_init_gsup(charstring id) runs on test_CT {
85 id := id & "-GSUP";
86 var GsupOps ops := {
87 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
88 };
89
90 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
91 vc_GSUP := GSUP_Emulation_CT.create(id);
92
93 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
94 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
95 /* we use this hack to get events like ASP_IPA_EVENT_UP */
96 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
97
98 vc_GSUP.start(GSUP_Emulation.main(ops, id));
99 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
100
101 /* wait for incoming connection to GSUP port before proceeding */
102 timer T := 10.0;
103 T.start;
104 alt {
105 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
106 [] T.timeout {
107 setverdict(fail, "No connection to GSUP Port");
108 self.stop;
109 }
110 }
111}
112
Harald Welte96a33b02018-02-04 10:36:22 +0100113function f_init() runs on test_CT {
114 if (g_initialized == true) {
115 return;
116 }
117 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100118 g_gb[0].cfg := {
119 nsei := 96,
120 bvci := 196,
121 cell_id := {
122 ra_id := {
123 lai := {
124 mcc_mnc := '26242F'H, lac := 13135},
125 rac := 0
126 },
127 cell_id := 20960
128 },
129 sgsn_role := false
130 };
Harald Welte96a33b02018-02-04 10:36:22 +0100131
Harald Welte5ac31492018-02-15 20:39:13 +0100132 f_init_gb(g_gb[0]);
133 f_init_gsup("SGSN_Test");
134}
Harald Welte96a33b02018-02-04 10:36:22 +0100135
Harald Welte5ac31492018-02-15 20:39:13 +0100136type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
137
138/* helper function to create, connect and start a BSSGP_ConnHdlr component */
139function f_start_handler(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix)
140runs on test_CT return BSSGP_ConnHdlr {
141 var BSSGP_ConnHdlr vc_conn;
142 var SGSN_ConnHdlrNetworkPars net_pars := {
143 expect_ptmsi := true,
144 expect_auth := true,
145 expect_ciph := false
146 };
147 var BSSGP_ConnHdlrPars pars := {
148 imei := f_gen_imei(imsi_suffix),
149 imsi := f_gen_imsi(imsi_suffix),
150 msisdn := f_gen_msisdn(imsi_suffix),
151 p_tmsi := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100152 tlli := f_gprs_tlli_random(),
Harald Welte5ac31492018-02-15 20:39:13 +0100153 ra := omit,
154 bssgp_cell_id := gb.cfg.cell_id,
155 vec := omit,
156 net := net_pars
157 };
158
159 vc_conn := BSSGP_ConnHdlr.create(id);
160 connect(vc_conn:BSSGP, gb.vc_BSSGP:BSSGP_SP);
161 connect(vc_conn:BSSGP_PROC, gb.vc_BSSGP:BSSGP_PROC);
162
163 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
164 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
165
166 vc_conn.start(f_handler_init(fn, id, pars));
167 return vc_conn;
168}
169
170/* first function called in every ConnHdlr */
171private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
172runs on BSSGP_ConnHdlr {
173 /* do some common stuff like setting up g_pars */
174 g_pars := pars;
175
176 /* register with BSSGP core */
177 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
178 /* tell GSUP dispatcher to send this IMSI to us */
179 f_create_gsup_expect(hex2str(g_pars.imsi));
180
181 /* call the user-supplied test case function */
182 fn.apply(id);
183 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100184}
185
186/* TODO:
187 * RAU without Attach
188 * Detach without Attach
189 * SM procedures without attach / RAU
190 * ATTACH / RAU
191 ** with / without authentication
192 ** with / without P-TMSI allocation
193 ** timeout from HLR on SAI
194 ** timeout from HLR on UL
195 ** reject from HLR on SAI
196 ** reject from HLR on UL
197 * re-transmissions of LLC frames
198 * PDP Context activation
199 ** with different GGSN config in SGSN VTY
200 ** with different PDP context type (v4/v6/v46)
201 ** timeout from GGSN
202 ** reject from GGSN
203 */
204
205testcase TC_wait_ns_up() runs on test_CT {
206 f_init();
207 f_sleep(20.0);
208}
209
Harald Welte5ac31492018-02-15 20:39:13 +0100210altstep as_mm_identity() runs on BSSGP_ConnHdlr {
211 var MobileIdentityLV mi;
212 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
213 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
214 BSSGP.send(ts_GMM_ID_RESP(mi));
215 repeat;
216 }
217 [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
218 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
219 BSSGP.send(ts_GMM_ID_RESP(mi));
220 repeat;
221 }
222}
Harald Welte96a33b02018-02-04 10:36:22 +0100223
Harald Welte5ac31492018-02-15 20:39:13 +0100224function f_gmm_auth () runs on BSSGP_ConnHdlr {
225 var BssgpDecoded bd;
226 var PDU_L3_MS_SGSN l3_mo;
227 var PDU_L3_SGSN_MS l3_mt;
228 var default di := activate(as_mm_identity());
229 if (g_pars.net.expect_auth) {
230 g_pars.vec := f_gen_auth_vec_2g();
231 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
232 g_pars.vec.sres,
233 g_pars.vec.kc));
234 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
235 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
236 BSSGP.receive(tr_BD_L3_MT(tr_GMM_AUTH_REQ(g_pars.vec.rand))) -> value bd;
237 l3_mt := bd.l3_mt;
238 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
239 l3_mo := valueof(ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres));
240 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
241 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
242 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
243 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
244 }
245 BSSGP.send(l3_mo);
246 }
247 deactivate(di);
248}
249
250private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
251 var MobileIdentityLV mi;
252 var RoutingAreaIdentificationV old_ra := { '2'H, '6'H, '2'H, 'F'H, '4'H, '2'H, '2342'O, '00'O };
253
254 if (ispresent(g_pars.p_tmsi)) {
255 mi := valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
256 } else {
257 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
258 }
259
260 BSSGP.send(ts_GMM_ATTACH_REQ(mi, old_ra, false, false, omit, omit));
261 f_gmm_auth();
262 /* Expect MSC to perform LU with HLR */
263 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
264 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
265 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
266 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
267
268 BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(?, ?, ?)));
269 BSSGP.send(ts_GMM_ATTACH_COMPL);
270/*
271 alt {
272 [] as_mm_identity();
273 }
274*/
275 f_sleep(5.0);
276}
277
278testcase TC_attach() runs on test_CT {
279 var BSSGP_ConnHdlr vc_conn;
280 f_init();
281 f_sleep(1.0);
282 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1);
283 vc_conn.done;
284}
285
286
287control {
288 execute( TC_wait_ns_up() );
289}
Harald Welte96a33b02018-02-04 10:36:22 +0100290
291
292
293}