blob: 17a4d60dc2c774c4a81b8ca249d19cd67970d03a [file] [log] [blame]
Harald Welteb8a4ac82019-06-23 11:04:12 +02001/* MME (Mobility Management Engine) test suite in TTCN-3
2 * (C) 2019 Harald Welte <laforge@gnumonks.org>
3 * All rights reserved.
4 *
5 * Released under the terms of GNU General Public License, Version 2 or
6 * (at your option) any later version.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11module MME_Tests {
12
Harald Welte95333a12019-07-11 22:51:45 +080013import from General_Types all;
Philipp Maier74d776a2023-07-12 14:04:14 +020014import from Native_Functions all;
15import from IPL4asp_Types all;
Harald Welte95333a12019-07-11 22:51:45 +080016import from S1AP_Types all;
17import from S1AP_Templates all;
18import from S1AP_Emulation all;
19import from S1AP_PDU_Descriptions all;
20import from S1AP_IEs all;
Philipp Maiera9306202023-07-24 11:41:51 +020021import from S1AP_PDU_Contents all;
22import from S1AP_Constants all;
Harald Welte95333a12019-07-11 22:51:45 +080023
24import from NAS_EPS_Types all;
25import from NAS_Templates all;
26
Harald Welte6ec64392019-08-14 12:37:07 +020027import from DIAMETER_Types all;
28import from DIAMETER_Templates all;
29import from DIAMETER_Emulation all;
30
Harald Welteb8a4ac82019-06-23 11:04:12 +020031import from SGsAP_Types all;
32import from SGsAP_Templates all;
33import from SGsAP_Emulation all;
34
Philipp Maier74d776a2023-07-12 14:04:14 +020035import from GTP_Emulation all;
36import from GTP_Templates all;
37import from GTP_CodecPort all;
38import from GTPC_Types all;
39
Harald Welte95333a12019-07-11 22:51:45 +080040import from LTE_CryptoFunctions all;
41
Harald Welteb8a4ac82019-06-23 11:04:12 +020042import from L3_Templates all;
43import from DNS_Helpers all;
Harald Welte95333a12019-07-11 22:51:45 +080044import from Osmocom_Types all;
Philipp Maiera9306202023-07-24 11:41:51 +020045import from Osmocom_Gb_Types all;
Harald Welteb8a4ac82019-06-23 11:04:12 +020046
47friend module MME_Tests_SGsAP;
48
Harald Welte95333a12019-07-11 22:51:45 +080049/* (maximum) number of emulated eNBs */
50const integer NUM_ENB := 3;
51
52/* (maximum) number of emulated UEs */
53const integer NUM_UE := 3;
54
55/* parameters of emulated ENB */
56type record EnbParams {
57 Global_ENB_ID global_enb_id,
58 integer cell_identity,
59 SupportedTAs supported_tas
60}
61
62/* parameters of emulated UE */
63type record UeParams {
64 hexstring imsi
65}
66
Harald Welteb8a4ac82019-06-23 11:04:12 +020067type component MTC_CT {
Harald Welte95333a12019-07-11 22:51:45 +080068 /* S1 intreface of emulated ENBs */
69 var EnbParams g_enb_pars[NUM_ENB];
70 var S1AP_Emulation_CT vc_S1AP[NUM_ENB];
71 port S1AP_PT S1AP_UNIT[NUM_ENB];
72 port S1APEM_PROC_PT S1AP_PROC[NUM_ENB];
73
Harald Welte6ec64392019-08-14 12:37:07 +020074 /* S6a/S6d interface of emulated HSS */
75 var DIAMETER_Emulation_CT vc_DIAMETER;
76 port DIAMETER_PT DIAMETER_UNIT;
77 port DIAMETEREM_PROC_PT DIAMETER_PROC;
78
Harald Welte95333a12019-07-11 22:51:45 +080079 /* SGs interface of emulated MSC/VLR */
Harald Welteb8a4ac82019-06-23 11:04:12 +020080 var SGsAP_Emulation_CT vc_SGsAP;
81 port SGsAP_PT SGsAP_UNIT;
82 port SGsAPEM_PROC_PT SGsAP_PROC;
Harald Welte95333a12019-07-11 22:51:45 +080083
Philipp Maier74d776a2023-07-12 14:04:14 +020084 /* Gn interface (GTPv1C) of emulated SGSN (Rel. 7) */
85 var GTP_Emulation_CT vc_GTP;
86
Harald Welte95333a12019-07-11 22:51:45 +080087 var UeParams g_ue_pars[NUM_UE];
Harald Welteb8a4ac82019-06-23 11:04:12 +020088}
89
Philipp Maiera9306202023-07-24 11:41:51 +020090/* Encode an S1AP Global-ENB-ID into an octetstring */
91private function enc_S1AP_Global_ENB_ID(Global_ENB_ID global_enb_id) return octetstring {
92
93 /* Due to the limitations of libfftranscode, we can not define encoders (or decoders) for individual
94 * information elements (in S1AP_Types.cc). Unfortuantely Global-ENB-ID also appears in BSSGP in its
95 * encoded form. (see also: GTP-C 3GPP TS 48.018, section 11.3.70). To encode a given Global-ENB-ID
96 * we craft a full S1AP PDU and encode it. Then we can cut out the encoded Global-ENB-ID from the
97 * generated octetstring. */
98
99 var SupportedTAs supported_tas_dummy := {{
100 tAC := '0000'O,
101 broadcastPLMNs := { '00f000'O },
102 iE_Extensions := omit
103 }};
104 var octetstring encoded;
105 var integer global_enb_id_len;
106
107 if (ispresent(global_enb_id.eNB_ID.macroENB_ID)) {
108 global_enb_id_len := 8;
109 } else {
110 /* All other ENB ID types fit into 8 byte (homeENB_ID, short_macroENB_ID, long_macroENB_ID) */
111 global_enb_id_len := 9;
112 }
113
114 encoded := enc_S1AP_PDU(valueof(ts_S1AP_SetupReq(global_enb_id, supported_tas_dummy, v32)));
115
116 return substr(encoded, 11, global_enb_id_len);
117}
118
Philipp Maier74d776a2023-07-12 14:04:14 +0200119type component ConnHdlr extends S1AP_ConnHdlr, SGsAP_ConnHdlr, DIAMETER_ConnHdlr, GTP_ConnHdlr {
Harald Welteb8a4ac82019-06-23 11:04:12 +0200120 var ConnHdlrPars g_pars;
121 timer g_Tguard := 30.0;
Philipp Maier74d776a2023-07-12 14:04:14 +0200122
123 var GtpPeer g_gn_iface_peer := { connId := 1, remName := mp_gn_remote_ip, remPort := mp_gn_local_port };
Harald Welteb8a4ac82019-06-23 11:04:12 +0200124}
125
126type record ConnHdlrPars {
Harald Welte95333a12019-07-11 22:51:45 +0800127 /* copied over from MTC_CT on start of component */
128 EnbParams enb_pars[NUM_ENB],
129 /* copied over from MTC_CT on start of component */
130 UeParams ue_pars,
131 /* currently used MME (index into enb_pars, S1AP, ...) */
132 integer mme_idx
Harald Welteb8a4ac82019-06-23 11:04:12 +0200133}
134
135modulepar {
Harald Welte95333a12019-07-11 22:51:45 +0800136 /* S1 interface */
137 charstring mp_mme_ip := "127.0.0.1";
138 integer mp_mme_s1ap_port := 36412;
139 charstring mp_s1_local_ip := "127.0.0.1";
140 integer mp_s1_local_port := 50000;
141
Harald Welte6ec64392019-08-14 12:37:07 +0200142 /* S6 interface */
143 charstring mp_s6_local_ip := "127.0.0.4";
144 integer mp_s6_local_port := 3868;
145
Harald Welte95333a12019-07-11 22:51:45 +0800146 /* SGs interface */
Harald Welteb8a4ac82019-06-23 11:04:12 +0200147 charstring mp_sgs_local_ip := "127.0.0.1";
148 integer mp_sgs_local_port := 29118;
149 charstring mp_vlr_name := "vlr.example.net";
150 charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";
Philipp Maier74d776a2023-07-12 14:04:14 +0200151
152 /* Gn interface (GTPv1C) */
153 charstring mp_gn_local_ip := "127.0.0.22";
154 integer mp_gn_local_port := 2123;
155 charstring mp_gn_remote_ip := "127.0.0.2";
Harald Welteb8a4ac82019-06-23 11:04:12 +0200156}
157
158/* send incoming unit data messages (like reset) to global SGsAP_UNIT port */
159friend function ForwardUnitdataCallback(PDU_SGsAP msg)
160runs on SGsAP_Emulation_CT return template PDU_SGsAP {
161 SGsAP_UNIT.send(msg);
162 return omit;
163}
164
165friend function f_init_sgsap(charstring id) runs on MTC_CT {
166 id := id & "-SGsAP";
167 var SGsAPOps ops := {
168 create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
169 unitdata_cb := refers(ForwardUnitdataCallback)
170 }
171 var SGsAP_conn_parameters pars := {
172 remote_ip := "",
173 remote_sctp_port := -1,
174 local_ip := mp_sgs_local_ip,
175 local_sctp_port := mp_sgs_local_port
176 }
177
178 vc_SGsAP := SGsAP_Emulation_CT.create(id);
179 map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
180 connect(vc_SGsAP:SGsAP_PROC, self:SGsAP_PROC);
181 connect(vc_SGsAP:SGsAP_UNIT, self:SGsAP_UNIT);
182 vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
183}
184
Harald Welte95333a12019-07-11 22:51:45 +0800185/* send incoming unit data messages (like reset) to global S1AP_UNIT port */
186friend function S1apForwardUnitdataCallback(S1AP_PDU msg)
187runs on S1AP_Emulation_CT return template S1AP_PDU {
188 S1AP_UNIT.send(msg);
189 return omit;
190}
191
Harald Welte95333a12019-07-11 22:51:45 +0800192friend function f_init_one_enb(charstring id, integer num := 0) runs on MTC_CT {
193 id := id & "-S1AP" & int2str(num);
194 var S1APOps ops := {
Philipp Maier7147c922023-07-07 14:18:32 +0200195 create_cb := refers(S1AP_Emulation.ExpectedCreateCallback),
Harald Welte95333a12019-07-11 22:51:45 +0800196 unitdata_cb := refers(S1apForwardUnitdataCallback)
197 }
198 var S1AP_conn_parameters pars := {
199 remote_ip := mp_mme_ip,
200 remote_sctp_port := mp_mme_s1ap_port,
201 local_ip := mp_s1_local_ip,
202 local_sctp_port := mp_s1_local_port + num,
203 role := NAS_ROLE_UE
204 }
205 var PLMNidentity plmn_id := '00f110'O;
206 var EnbParams enb_pars := {
207 global_enb_id := {
208 pLMNidentity := plmn_id,
209 eNB_ID := {
210 macroENB_ID := int2bit(num, 20)
211 },
212 iE_Extensions := omit
213 },
214 cell_identity := num,
215 supported_tas := {
216 {
217 tAC := int2oct(12345, 2),
218 broadcastPLMNs := { plmn_id },
219 iE_Extensions := omit
220 }
221 }
222 };
223
224 g_enb_pars[num] := enb_pars;
225 vc_S1AP[num] := S1AP_Emulation_CT.create(id);
226 map(vc_S1AP[num]:S1AP, system:S1AP_CODEC_PT);
227 connect(vc_S1AP[num]:S1AP_PROC, self:S1AP_PROC[num]);
228 connect(vc_S1AP[num]:S1AP_UNIT, self:S1AP_UNIT[num]);
229 vc_S1AP[num].start(S1AP_Emulation.main(ops, pars, id));
230 S1AP_UNIT[num].receive(S1APEM_Event:{up_down:=S1APEM_EVENT_UP});
231}
232friend function f_init_one_ue(inout UeParams uep, integer imsi_suffix) {
233 uep := {
234 imsi := f_gen_imsi(imsi_suffix)
235 }
236}
237friend function f_init_s1ap(charstring id, integer imsi_suffix) runs on MTC_CT {
238 var integer i;
239 for (i := 0; i < NUM_ENB; i := i+1) {
240 f_init_one_enb(id, i);
241 }
242 for (i := 0; i < NUM_UE; i := i+1) {
243 f_init_one_ue(g_ue_pars[i], i*1000 + imsi_suffix);
244 }
245}
246
Harald Welte6ec64392019-08-14 12:37:07 +0200247friend function DiameterForwardUnitdataCallback(PDU_DIAMETER msg)
248runs on DIAMETER_Emulation_CT return template PDU_DIAMETER {
249 DIAMETER_UNIT.send(msg);
250 return omit;
251}
252
253friend function f_init_diameter(charstring id) runs on MTC_CT {
254 var DIAMETEROps ops := {
255 create_cb := refers(DIAMETER_Emulation.ExpectedCreateCallback),
Vadim Yanitskiyb46f01e2021-12-06 03:23:13 +0300256 unitdata_cb := refers(DiameterForwardUnitdataCallback),
257 raw := false /* handler mode (IMSI based routing) */
Harald Welte6ec64392019-08-14 12:37:07 +0200258 };
259 var DIAMETER_conn_parameters pars := {
260 remote_ip := mp_mme_ip,
261 remote_sctp_port := -1,
262 local_ip := mp_s6_local_ip,
Harald Welte61f73d52020-04-26 21:41:12 +0200263 local_sctp_port := mp_s6_local_port,
264 origin_host := "hss.localdomain",
265 origin_realm := "localdomain",
Pau Espin Pedrol33b47492022-03-08 17:43:01 +0100266 auth_app_id := omit,
Harald Welte61f73d52020-04-26 21:41:12 +0200267 vendor_app_id := c_DIAMETER_3GPP_S6_AID
Harald Welte6ec64392019-08-14 12:37:07 +0200268 };
269 vc_DIAMETER := DIAMETER_Emulation_CT.create(id);
270 map(vc_DIAMETER:DIAMETER, system:DIAMETER_CODEC_PT);
271 connect(vc_DIAMETER:DIAMETER_UNIT, self:DIAMETER_UNIT);
272 connect(vc_DIAMETER:DIAMETER_PROC, self:DIAMETER_PROC);
273 vc_DIAMETER.start(DIAMETER_Emulation.main(ops, pars, id));
Harald Welted01b5d02020-04-26 22:05:53 +0200274
275 f_diameter_wait_capability(DIAMETER_UNIT);
Harald Welte6ec64392019-08-14 12:37:07 +0200276}
277
Philipp Maier74d776a2023-07-12 14:04:14 +0200278friend function f_init_gtp(charstring id) runs on MTC_CT {
279 id := id & "-GTP";
280
281 var GtpEmulationCfg gtp_cfg := {
282 gtpc_bind_ip := mp_gn_local_ip,
283 gtpc_bind_port := mp_gn_local_port,
284 gtpu_bind_ip := omit,
285 gtpu_bind_port := omit,
286 sgsn_role := true
287 };
288
289 vc_GTP := GTP_Emulation_CT.create(id);
290 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
291}
292
Harald Welte95333a12019-07-11 22:51:45 +0800293friend template (value) TAI ts_enb_S1AP_TAI(EnbParams enb) := {
294 pLMNidentity := enb.global_enb_id.pLMNidentity,
295 tAC := enb.supported_tas[0].tAC,
296 iE_Extensions := omit
297}
298
299friend template (value) EUTRAN_CGI ts_enb_S1AP_CGI(EnbParams enb) := {
300 pLMNidentity := enb.global_enb_id.pLMNidentity,
301 cell_ID := int2bit(enb.cell_identity, 28),
302 iE_Extensions := omit
303}
304
305
Harald Welteb8a4ac82019-06-23 11:04:12 +0200306/* generate parameters for a connection handler */
Harald Welte95333a12019-07-11 22:51:45 +0800307friend function f_init_pars(integer ue_idx := 0)
Harald Welteb8a4ac82019-06-23 11:04:12 +0200308runs on MTC_CT return ConnHdlrPars {
309 var ConnHdlrPars pars := {
Harald Welte95333a12019-07-11 22:51:45 +0800310 enb_pars := g_enb_pars,
311 ue_pars := g_ue_pars[ue_idx],
312 mme_idx := 0
Harald Welteb8a4ac82019-06-23 11:04:12 +0200313 };
314 return pars;
315}
316
317type function void_fn(ConnHdlrPars pars) runs on ConnHdlr;
318
319/* start a connection handler with given parameters */
320friend function f_start_handler_with_pars(void_fn fn, ConnHdlrPars pars, integer s1ap_idx := 0)
321runs on MTC_CT return ConnHdlr {
322 var ConnHdlr vc_conn;
323 var charstring id := testcasename() & int2str(s1ap_idx);
324
325 vc_conn := ConnHdlr.create(id);
Harald Welte95333a12019-07-11 22:51:45 +0800326 /* S1AP part */
327 connect(vc_conn:S1AP, vc_S1AP[s1ap_idx]:S1AP_CLIENT);
328 connect(vc_conn:S1AP_PROC, vc_S1AP[s1ap_idx]:S1AP_PROC);
329 if (isbound(vc_SGsAP)) {
330 /* SGsAP part */
331 connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
332 connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
333 }
Harald Welte6ec64392019-08-14 12:37:07 +0200334 if (isbound(vc_DIAMETER)) {
335 connect(vc_conn:DIAMETER, vc_DIAMETER:DIAMETER_CLIENT);
336 connect(vc_conn:DIAMETER_PROC, vc_DIAMETER:DIAMETER_PROC);
337 }
Philipp Maier74d776a2023-07-12 14:04:14 +0200338 if (isbound(vc_GTP)) {
339 connect(vc_conn:GTP, vc_GTP:CLIENT);
340 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
341 }
Harald Welteb8a4ac82019-06-23 11:04:12 +0200342
343 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
344 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
345 vc_conn.start(derefers(fn)(pars));
346 return vc_conn;
347}
348
349/* altstep for the global guard timer */
350private altstep as_Tguard()runs on ConnHdlr {
351 [] g_Tguard.timeout {
352 setverdict(fail, "Tguard timeout");
353 mtc.stop;
354 }
355}
356
357friend function f_init_handler(ConnHdlrPars pars, float t_guard := 30.0) runs on ConnHdlr {
358 /* make parameters available via component variable */
359 g_pars := pars;
360 /* start guard timre and activate it as default */
361 g_Tguard.start(t_guard);
362 activate(as_Tguard());
Harald Welte6ec64392019-08-14 12:37:07 +0200363 if (DIAMETER_PROC.checkstate("Connected")) {
364 f_diameter_expect(g_pars.ue_pars.imsi);
365 }
Harald Welte95333a12019-07-11 22:51:45 +0800366 if (SGsAP_PROC.checkstate("Connected")) {
367 /* Route all SGsAP mesages for our IMSIto us */
368 f_create_sgsap_expect(pars.ue_pars.imsi);
369 }
370}
371
372
373
374friend function f_s1ap_setup(integer idx := 0, template Cause cause := omit) runs on MTC_CT {
375 var template (present) Cause exp_cause;
376 var boolean exp_fail := false;
377 timer T := 5.0;
378 if (not istemplatekind(cause, "omit")) {
379 exp_fail := true;
380 exp_cause := cause;
381 }
382
383 S1AP_UNIT[idx].send(ts_S1AP_SetupReq(g_enb_pars[idx].global_enb_id,
384 g_enb_pars[idx].supported_tas, v32));
385 T.start;
386 alt {
387 [exp_fail] S1AP_UNIT[idx].receive(tr_S1AP_SetupFail(exp_cause)) {
388 setverdict(pass);
389 }
390 [not exp_fail] S1AP_UNIT[idx].receive(tr_S1AP_SetupResp) {
391 setverdict(pass);
392 }
393 [] S1AP_UNIT[idx].receive {
394 setverdict(fail, "Received unexpected S1AP");
395 }
396 [] T.timeout {
397 setverdict(fail, "Timeout waiting for S1AP Setup result");
398 }
399 }
400}
401
402/* Unsuccessful S1 Setup procedure to MME (wrong PLMN) */
403testcase TC_s1ap_setup_wrong_plmn() runs on MTC_CT {
404 var charstring id := testcasename();
405 f_init_s1ap(id, 1);
406 g_enb_pars[0].global_enb_id.pLMNidentity := '62F224'O;
407 f_s1ap_setup(0, {misc:=unknown_PLMN});
408}
409
410/* Unsuccessful S1 Setup procedure to MME (wrong PLMN) */
411testcase TC_s1ap_setup_wrong_tac() runs on MTC_CT {
412 var charstring id := testcasename();
413 f_init_s1ap(id, 2);
414 g_enb_pars[0].supported_tas[0].broadcastPLMNs[0] := '62F224'O;
415 f_s1ap_setup(0, {misc:=unknown_PLMN});
416}
417
418/* Successful S1 Setup procedure to MME */
419testcase TC_s1ap_setup() runs on MTC_CT {
420 var charstring id := testcasename();
421 f_init_s1ap(id, 3);
422 f_s1ap_setup(0);
423}
424
425private const EPS_QualityOfServiceV c_NAS_defaultQoS := {
426 qCI := '00'O,
427 maxBitRateUplink := omit,
428 maxBitRateDownlink := omit,
429 guaranteedBitRateUplink := omit,
430 guaranteedBitRateDownlink := omit,
431 maxBitRateUplinkExt := omit,
432 maxBitRateDownlinkExt := omit,
433 guaranteedBitRateUplinkExt := omit,
434 guaranteedBitRateDownlinkExt := omit,
435 maxBitRateUplinkExt2 := omit,
436 maxBitRateDownlinkExt2 := omit,
437 guaranteedBitRateUplinkExt2 := omit,
438 guaranteedBitRateDownlinkExt2 := omit
439};
440
441private const UENetworkCapabilityV c_NAS_defaultUeNetCap := {
442 eEA := '10000000'B,
443 eIA := '11000000'B,
444 uEA := omit,
445 uIA := omit,
446 uCS2 := omit,
447 nF := omit,
448 vCC := omit,
449 lCS := omit,
450 lPP := omit,
451 aCC_CSFB := omit,
452 h245_ASH := omit,
453 proSe := omit,
454 proSe_dd := omit,
455 proSe_dc := omit,
456 proSe_relay := omit,
457 cP_CIoT := omit,
458 uP_CIoT := omit,
459 s1_Udata := omit,
460 eRwoPDN := omit,
461 hC_CP_CIoT := omit,
462 ePCO := omit,
463 multipleDRB := omit,
464 v2XPC5 := omit,
465 restrictEC := omit,
466 cPbackoff := omit,
467 dCNR := omit,
468 n1Mode := omit,
469 sGC := omit,
470 spare1 := omit,
471 spare := omit
472};
473
474private const octetstring c_NAS_defaultAPN := '00'O;
475
476private altstep as_s1ap_handle_auth() runs on ConnHdlr {
477 var PDU_NAS_EPS rx_nas;
478 [] S1AP.receive(tr_NAS_AuthReq) -> value rx_nas {
479 /* static XRES result as we fixed the HSS RAND value and always have the following
480 RAND: 20080c3818183b522614162c07601d0d
481 AUTN: f11b89a2a8be00001f9c526f3d75d44c
482 IK: 11329aae8e8d2941bb226b2061137c58
483 CK: 740d62df9803eebde5120acf358433d0
484 RES: 6a91970e838fd079
485 SRES: e91e4777
486 Kc: 3b0f999e42198874
487 SQN: 32
488 IND: 0
489 */
490 /* KASME: 95AFAD9A0D29AFAA079A9451DF7161D7EE4CBF2AF9387F766D058BB6B44B905D */
491 const OCT16 ck := '740d62df9803eebde5120acf358433d0'O;
492 const OCT16 ik := '11329aae8e8d2941bb226b2061137c58'O;
493 const OCT16 autn := 'f11b89a2a8be00001f9c526f3d75d44c'O;
494 const OCT8 res := '6a91970e838fd079'O;
495 const OCT3 plmn_id := '00F110'O;
496 const OCT6 sqn := '000000000020'O;
497 const OCT6 ak := substr(autn, 0, 6) xor4b sqn;
498 var octetstring kasme := f_kdf_kasme(ck, ik, plmn_id, sqn, ak);
499 var S1APEM_Config cfg := {
500 set_nas_keys := {
501 k_nas_int := f_kdf_nas_int(1, kasme),
502 k_nas_enc := f_kdf_nas_enc(1, kasme)
503 }
504 };
505 S1AP.send(cfg);
506 S1AP.send(ts_NAS_AuthResp(res));
507 }
508}
509
510private altstep as_s1ap_handle_sec_mode() runs on ConnHdlr {
511 var PDU_NAS_EPS rx_nas;
512 var NAS_SecurityAlgorithmsV alg := {
513 typeOfIntegrityProtection := '001'B,
514 spare1 := '0'B,
515 typeOfCiphering := '000'B,
516 spare2 := '0'B
517 };
518 var NAS_KeySetIdentifierV kset_id := {
519 identifier := '000'B,
520 tSC := '0'B
521 };
522 [] S1AP.receive(tr_NAS_SecModeCmd(alg, kset_id, ?)) {
523 S1AP.send(ts_NAS_SecModeCmpl);
524 }
525}
526
Harald Welte6ec64392019-08-14 12:37:07 +0200527/* Exepect AuthInfoReq (AIR) from HSS; respond with AuthInforAnswer (AIA) */
528private altstep as_DIA_AuthInfo() runs on ConnHdlr {
529 var PDU_DIAMETER rx_dia;
530 [] DIAMETER.receive(tr_DIA_AIR(g_pars.ue_pars.imsi)) -> value rx_dia {
531 var template (omit) AVP avp;
532 var octetstring sess_id;
533 var octetstring vplmn_id;
534 var hexstring imsi;
535 var template (value) AVP_list auth_info_content;
536
537 /* retrieve input data */
538 imsi := valueof(f_DIAMETER_get_imsi(rx_dia));
539 avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id);
540 sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);
541 avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_AAA_3GPP_Visited_PLMN_Id);
542 vplmn_id := valueof(avp.avp_data.avp_AAA_3GPP_Visited_PLMN_Id);
543
544 /* compute tuple */
545 auth_info_content := { ts_AVP_EutranVec(1, '20080c3818183b522614162c07601d0d'O, '6a91970e838fd079'O, 'f11b89a2a8be00001f9c526f3d75d44c'O, '95AFAD9A0D29AFAA079A9451DF7161D7EE4CBF2AF9387F766D058BB6B44B905D'O) };
546
Vadim Yanitskiy2dba4942021-12-11 15:46:30 +0300547 DIAMETER.send(ts_DIA_AIA(auth_info_content, sess_id,
548 hbh_id := rx_dia.hop_by_hop_id,
549 ete_id := rx_dia.end_to_end_id));
Harald Welte6ec64392019-08-14 12:37:07 +0200550 }
551}
552
553/* Expect UpdateLocationReq (ULR); respond with UpdateLocationAnswer (ULA) */
554private altstep as_DIA_UpdLoc() runs on ConnHdlr {
555 var PDU_DIAMETER rx_dia;
556 [] DIAMETER.receive(tr_DIA_ULR(g_pars.ue_pars.imsi)) -> value rx_dia {
557 var template (omit) AVP avp;
Harald Welte6ec64392019-08-14 12:37:07 +0200558 var hexstring imsi;
559 var template (value) AVP_list sub_data;
560
561 /* retrieve input data */
562 imsi := valueof(f_DIAMETER_get_imsi(rx_dia));
563 avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id);
Harald Welte6ec64392019-08-14 12:37:07 +0200564
565 sub_data := {
566 ts_AVP_3GPP_SubscriberStatus(SERVICE_GRANTED),
567 ts_AVP_3GPP_SubscrRauTauTmr(30),
568 ts_AVP_3GPP_AMBR(1000, 2000),
569 ts_AVP_3GPP_ApnConfigProfile({
570 ts_AVP_3GPP_ContextId(1),
571 ts_AVP_3GPP_AllApnConfigsIncl,
572 ts_AVP_3GPP_ApnConfig(1, IPv4, "*")
573 })
574 };
575
Vadim Yanitskiy0e8f5162021-12-15 05:00:32 +0300576 DIAMETER.send(ts_DIA_ULA(sub_data, avp.avp_data.avp_BASE_NONE_Session_Id,
577 hbh_id := rx_dia.hop_by_hop_id,
578 ete_id := rx_dia.end_to_end_id));
Harald Welte6ec64392019-08-14 12:37:07 +0200579 }
580}
581
Harald Welte95333a12019-07-11 22:51:45 +0800582private function f_TC_attach(ConnHdlrPars pars) runs on ConnHdlr {
Harald Welte6ec64392019-08-14 12:37:07 +0200583
Harald Welte95333a12019-07-11 22:51:45 +0800584 f_init_handler(pars);
Harald Welte6ec64392019-08-14 12:37:07 +0200585 var template (value) EPS_MobileIdentityV mi := ts_NAS_MobileId_IMSI(pars.ue_pars.imsi);
Harald Welte95333a12019-07-11 22:51:45 +0800586 var template (value) PDU_NAS_EPS nas_esm, nas_emm;
587/*
588 nas_esm := ts_NAS_ActDefEpsBearCtxReq(bearer_id := '0000'B, proc_tid := int2bit(1,8),
589 qos := c_NAS_defaultQoS, apn := c_NAS_defaultAPN,
590 addr_type := '000'B, addr_info := ''O);
591*/
592 nas_esm := ts_NAS_PdnConnReq(bearer_id := '0000'B, proc_tid := int2bit(1,8),
593 pdn_type := NAS_PDN_T_IPv4, req_type := '001'B);
594 nas_emm := ts_NAS_AttachRequest(att_type := '000'B, kset_id := '000'B, mobile_id := mi,
595 ue_net_cap := c_NAS_defaultUeNetCap,
596 esm_enc := enc_PDU_NAS_EPS(valueof(nas_esm)));
597 var template (value) S1AP_PDU tx;
598 tx := ts_S1AP_InitialUE(p_eNB_value := 0, p_nasPdu := enc_PDU_NAS_EPS(valueof(nas_emm)),
599 p_tAI := ts_enb_S1AP_TAI(g_pars.enb_pars[g_pars.mme_idx]),
600 p_eUTRAN_CGI := ts_enb_S1AP_CGI(g_pars.enb_pars[g_pars.mme_idx]),
601 p_rrcCause := mo_Signalling);
602 S1AP.send(tx);
603
Harald Welte6ec64392019-08-14 12:37:07 +0200604 as_DIA_AuthInfo();
Harald Welte95333a12019-07-11 22:51:45 +0800605 as_s1ap_handle_auth();
Harald Welte6ec64392019-08-14 12:37:07 +0200606 alt {
607 [] as_DIA_UpdLoc() {
608 as_s1ap_handle_sec_mode();
609 }
610 [] as_s1ap_handle_sec_mode() {
611 as_DIA_UpdLoc();
612 }
613 }
Harald Welte95333a12019-07-11 22:51:45 +0800614
615 f_sleep(10.0);
616}
617testcase TC_s1ap_attach() runs on MTC_CT {
618 var charstring id := testcasename();
619
Harald Welte6ec64392019-08-14 12:37:07 +0200620 f_init_diameter(id);
621 f_sleep(10.0);
Harald Welte95333a12019-07-11 22:51:45 +0800622 f_init_s1ap(id, 4);
623 f_s1ap_setup(0);
624
625 var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
626 var ConnHdlr vc_conn;
627 vc_conn := f_start_handler_with_pars(refers(f_TC_attach), pars);
628 vc_conn.done;
629}
630
Philipp Maier74d776a2023-07-12 14:04:14 +0200631private function f_TC_gn_echo_request(ConnHdlrPars pars) runs on ConnHdlr {
632 timer T := 5.0;
633 f_init_handler(pars);
634 f_gtp_register_teid('00000000'O);
635
636 GTP.send(ts_GTPC_PING(g_gn_iface_peer, 1));
637 T.start;
638 alt {
639 [] GTP.receive(tr_GTPC_PONG(?)) {
640 setverdict(pass);
641 }
642 [] GTP.receive {
643 setverdict(fail, "unexpected GTPC message from MME");
644 }
645 [] T.timeout {
646 setverdict(fail, "no GTPC ECHO RESPONSE from MME");
647 }
648 }
649}
650testcase TC_gn_echo_request() runs on MTC_CT {
651 var charstring id := testcasename();
652
653 f_init_diameter(id);
654 f_init_s1ap(id, 4);
655 f_s1ap_setup(0);
656 f_init_gtp(id);
657
658 var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
659 var ConnHdlr vc_conn;
660 vc_conn := f_start_handler_with_pars(refers(f_TC_gn_echo_request), pars);
661 vc_conn.done;
662}
663
Philipp Maiera9306202023-07-24 11:41:51 +0200664external function enc_PDU_GTPC_RAN_INF_REQ(in PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_pdu) return octetstring
665with { extension "prototype(convert)"
666 extension "encode(RAW)"
667 }
668
669external function enc_PDU_GTPC_RAN_INF(in PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_pdu) return octetstring
670with { extension "prototype(convert)"
671 extension "encode(RAW)"
672 }
673
674function f_convert_plmn(OCT3 pLMNidentity) return hexstring {
675 var hexstring pLMNidentity_hex := oct2hex(pLMNidentity);
676 var hexstring pLMNidentity_hex_swapped;
677 pLMNidentity_hex_swapped[0] := pLMNidentity_hex[1];
678 pLMNidentity_hex_swapped[1] := pLMNidentity_hex[0];
679 pLMNidentity_hex_swapped[2] := pLMNidentity_hex[3];
680 pLMNidentity_hex_swapped[3] := pLMNidentity_hex[2];
681 pLMNidentity_hex_swapped[4] := pLMNidentity_hex[5];
682 pLMNidentity_hex_swapped[5] := pLMNidentity_hex[4];
683 return pLMNidentity_hex_swapped;
684}
685
686/* Make a template for a GTPC BSSGP container that contains a RAN INFORMATION REQUEST. The template can be used to
687 * craft the request for the S1AP/S1-MME interface and also to verfify the contents of the coresponding request on
688 * the GTPC/Gn interface */
689private function f_make_ts_GTPC_RAN_Information_Request(GTP_CellId geran_gtp_ci)
690 runs on ConnHdlr return template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC {
691 var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
692 var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
693 var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
694 var octetstring gnbid;
695 var GTP_CellId eutran_gtp_ci;
696 eutran_gtp_ci.ra_id.lai.mcc_mnc := f_convert_plmn(g_pars.enb_pars[g_pars.mme_idx].global_enb_id.pLMNidentity);
697
698 gnbid := enc_S1AP_Global_ENB_ID(g_pars.enb_pars[g_pars.mme_idx].global_enb_id);
699 gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(geran_gtp_ci);
700 gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(eutran_gtp_ci,
701 oct2int(g_pars.enb_pars[g_pars.mme_idx].supported_tas[0].tAC),
702 gnbid);
703
704 gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(
705 ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
706 ts_GTPC_RIM_Sequence_Number(1),
707 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
708 ts_GTPC_RIM_Protocol_Version_Number(1),
709 tsu_GTPC_RAN_Information_Request_Application_Container_NACC(geran_gtp_ci),
710 omit);
711 gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(
712 ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
713 ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
714 gtpc_rim_req_cont);
715
716 return gtpc_bssgp_cont;
717}
718
719private function f_make_tr_GTPC_RAN_Information_Request(GTP_CellId geran_gtp_ci)
720 runs on ConnHdlr return template (present) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC {
721 var template (present) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
722 var template (present) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
723 var template (present) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
724 var octetstring gnbid;
725 var GTP_CellId eutran_gtp_ci;
726 eutran_gtp_ci.ra_id.lai.mcc_mnc := f_convert_plmn(g_pars.enb_pars[g_pars.mme_idx].global_enb_id.pLMNidentity);
727
728 gnbid := enc_S1AP_Global_ENB_ID(g_pars.enb_pars[g_pars.mme_idx].global_enb_id);
729 gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(geran_gtp_ci);
730 gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(eutran_gtp_ci,
731 oct2int(g_pars.enb_pars[g_pars.mme_idx].supported_tas[0].tAC),
732 gnbid);
733
734 gtpc_rim_req_cont := tr_GTPC_RAN_Information_Request_RIM_Container(
735 ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
736 ts_GTPC_RIM_Sequence_Number(1),
737 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
738 ts_GTPC_RIM_Protocol_Version_Number(1),
739 tru_GTPC_RAN_Information_Request_Application_Container_NACC(geran_gtp_ci));
740 gtpc_bssgp_cont := tr_GTPC_RAN_Information_Request(
741 tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
742 tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
743 gtpc_rim_req_cont);
744
745 return gtpc_bssgp_cont;
746}
747
748/* Make initial RAN INFORMATION REQUEST message that is sent on the S1AP/S1-MME interface */
749private function f_make_ts_S1AP_eNBDirectInfTrans(GTP_CellId geran_gtp_ci)
750 runs on ConnHdlr return template (value) S1AP_PDU {
751 var template (value) Inter_SystemInformationTransferType inf;
752
753 inf.rIMTransfer.rIMInformation := enc_PDU_GTPC_RAN_INF_REQ(valueof(f_make_ts_GTPC_RAN_Information_Request(geran_gtp_ci)));
754 inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.lAI.pLMNidentity := hex2oct(f_convert_plmn(hex2oct(geran_gtp_ci.ra_id.lai.mcc_mnc)));
755 inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.lAI.lAC := int2oct(geran_gtp_ci.ra_id.lai.lac, 2);
756 inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.lAI.iE_Extensions := omit;
757 inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.rAC := int2oct(geran_gtp_ci.ra_id.rac, 1);
758 inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.cI := int2oct(geran_gtp_ci.cell_id, 2);
759 inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.iE_Extensions := omit;
760 inf.rIMTransfer.iE_Extensions := omit;
761
762 return ts_S1AP_eNBDirectInfTrans(inf);
763}
764
765/* Make RAN INFORMATION (response) message that is sent on the GTPC/Gn interface */
766private function f_make_ts_GTPC_RANInfoRelay(template Gtp1cUnitdata req_gtpc_pdu,
767 GTP_CellId geran_gtp_ci, octetstring geran_si)
768 runs on ConnHdlr return template (value) Gtp1cUnitdata {
769 var template Gtp1cUnitdata res_gtpc_pdu;
770 var template RAN_Information_RIM_Container_GTPC gtpc_rim_res_cont;
771 var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_rim_res_pdu;
772 var template RIM_Routing_Information_GTPC gtpc_rim_dst_cell_id, gtpc_rim_src_cell_id;
773 var template RIM_RoutingAddress gtpc_rim_ra;
774 var template RIM_RoutingAddress_Discriminator gtpc_rim_ra_discr;
775
776 /* Assemble GTPC RAN Information */
777 gtpc_rim_res_cont := ts_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
778 ts_GTPC_RIM_Sequence_Number(2),
779 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
780 ts_GTPC_RIM_Protocol_Version_Number(1),
781 tsu_GTPC_ApplContainer_or_ApplErrContainer_NACC(tsu_GTPC_ApplContainer_NACC(geran_gtp_ci, false, 3, geran_si)),
782 omit);
783
784 /* The source becomes the destination and vice versa */
785 gtpc_rim_dst_cell_id := req_gtpc_pdu.gtpc.gtpc_pdu.ranInformationRelay.transparentContainer.
786 rANTransparentContainerField.pDU_BSSGP_RAN_INFORMATION_REQUEST.source_Cell_Identifier
787 gtpc_rim_src_cell_id := req_gtpc_pdu.gtpc.gtpc_pdu.ranInformationRelay.transparentContainer.
788 rANTransparentContainerField.pDU_BSSGP_RAN_INFORMATION_REQUEST.destination_Cell_Identifier
789 gtpc_bssgp_rim_res_pdu := ts_GTPC_RAN_Information(gtpc_rim_dst_cell_id,
790 gtpc_rim_src_cell_id,
791 gtpc_rim_res_cont);
792
793 /* Assemble RIM Routing Address (essentially a copy of the destination cell identifier)*/
794 gtpc_rim_ra := ts_RIM_RoutingAddress(enc_RIM_Routing_Address_GTPC(valueof(gtpc_rim_dst_cell_id.rIM_Routing_Address)));
795 gtpc_rim_ra_discr := ts_RIM_RoutingAddress_Discriminator(hex2bit(valueof(gtpc_rim_dst_cell_id.rIMRoutingAddressDiscriminator)));
796
797 res_gtpc_pdu := ts_GTPC_RANInfoRelay(g_gn_iface_peer,
798 ts_RANTransparentContainer_RAN_INFO(gtpc_bssgp_rim_res_pdu),
799 gtpc_rim_ra, gtpc_rim_ra_discr);
800
801 return res_gtpc_pdu;
802}
803
804/* Make template to verify the RAN INFORMATION REQUEST as it appears on the GTPC/Gn interface */
805private function f_make_tr_GTPC_MsgType(GTP_CellId geran_gtp_ci)
806 runs on ConnHdlr return template (present) Gtp1cUnitdata {
807 var template Gtp1cUnitdata msg;
808 var template GTPC_PDUs pdus;
809 var template RANTransparentContainer ran_transp_cont;
810
811 ran_transp_cont := tr_RANTransparentContainer_RAN_INFO_REQ(
812 f_make_tr_GTPC_RAN_Information_Request(geran_gtp_ci));
813 pdus := tr_RANInfoRelay(ran_transp_cont);
814 msg := tr_GTPC_MsgType(g_gn_iface_peer, rANInformationRelay, '00000000'O, pdus);
815
816 return msg;
817}
818
819/* Make template to verify the RAN INFORMATION (response) as it appears on the S1AP/S1-MME interface */
820private function f_make_tr_S1AP_MMEDirectInfTrans(Gtp1cUnitdata ran_information_gtpc_pdu)
821 runs on ConnHdlr return template (present) S1AP_PDU {
822 var template S1AP_PDU msg;
823 var template Inter_SystemInformationTransferType inf;
824
825 inf.rIMTransfer.rIMInformation := enc_PDU_GTPC_RAN_INF(
826 ran_information_gtpc_pdu.gtpc.gtpc_pdu.ranInformationRelay.
827 transparentContainer.rANTransparentContainerField.
828 pDU_BSSGP_RAN_INFORMATION);
829 inf.rIMTransfer.rIMRoutingAddress := omit;
830 inf.rIMTransfer.iE_Extensions := omit;
831 msg := tr_S1AP_MMEDirectInfTrans(inf);
832
833 return msg;
834}
835
836private function f_TC_RIM_RAN_INF(ConnHdlrPars pars) runs on ConnHdlr {
837 timer T := 5.0;
838 f_init_handler(pars);
839 f_gtp_register_teid('00000000'O);
840 var Gtp1cUnitdata req_gtpc_pdu;
841 var Gtp1cUnitdata resp_gtpc_pdu;
842 var GTP_CellId geran_gtp_ci;
843
844 /* Assemble data of a fictitiously GERAN cell */
845 geran_gtp_ci.ra_id.rac := oct2int('BB'O);
846 geran_gtp_ci.ra_id.lai.mcc_mnc := '262f42'H
847 geran_gtp_ci.ra_id.lai.lac := oct2int('AAAA'O);
848 geran_gtp_ci.cell_id := oct2int('04C7'O);
849 const octetstring geran_si1 := '198fb100000000000000000000000000007900002b'O;
850 const octetstring geran_si3 := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
851 const octetstring geran_si13 := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
852 const octetstring geran_si := geran_si1 & geran_si3 & geran_si13;
853
854 /* Send initial RAN information request via S1AP to MME and expect the MME to forward the request on GTP-C
855 * (eNB -> MME -> SGSN) */
856 S1AP.send(f_make_ts_S1AP_eNBDirectInfTrans(geran_gtp_ci));
857 T.start;
858 alt {
859 [] GTP.receive(f_make_tr_GTPC_MsgType(geran_gtp_ci)) -> value req_gtpc_pdu {
860 setverdict(pass);
861 }
862 [] GTP.receive {
863 setverdict(fail, "unexpected GTPC message from MME");
864 }
865 [] T.timeout {
866 setverdict(fail, "no GTPC RAN INFORMATION REQUEST from MME");
867 }
868 }
869
870 /* Send RAN information response via GTP-C to MME and expect the MME to forward the respnse on S1AP
871 * (SGSN -> MME -> eNB) */
872 f_create_s1ap_expect_proc(id_MMEDirectInformationTransfer, self);
873 resp_gtpc_pdu := valueof(f_make_ts_GTPC_RANInfoRelay(req_gtpc_pdu, geran_gtp_ci, geran_si));
874 GTP.send(resp_gtpc_pdu);
875 T.start;
876 alt {
877 [] S1AP.receive(f_make_tr_S1AP_MMEDirectInfTrans(resp_gtpc_pdu)) {
878 setverdict(pass);
879 }
880 [] S1AP.receive {
881 setverdict(fail, "unexpected S1AP message from MME");
882 }
883 [] T.timeout {
884 setverdict(fail, "no S1AP RAN INFORMATION from MME");
885 }
886 }
887
888 setverdict(pass);
889}
890
891testcase TC_RIM_RAN_INF() runs on MTC_CT {
892 var charstring id := testcasename();
893
894 f_init_diameter(id);
895 f_init_s1ap(id, 4);
896 f_s1ap_setup(0);
897 f_init_gtp(id);
898
899 timer T := 3.0;
900
901 var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
902 var ConnHdlr vc_conn;
903 vc_conn := f_start_handler_with_pars(refers(f_TC_RIM_RAN_INF), pars);
904
905 vc_conn.done;
906}
907
Philipp Maier46059f02023-08-16 14:45:27 +0200908/* Successful RESET procedure from eNB to MME */
909testcase TC_s1ap_reset() runs on MTC_CT {
910 var charstring id := testcasename();
911 f_init_s1ap(id, 3);
912 f_s1ap_setup(0);
913
914 var template (value) Cause reset_cause := {misc := om_intervention};
915 var template (value) ResetType reset_type := {s1_Interface := reset_all};
916 timer T := 5.0;
917
918 S1AP_UNIT[0].send(ts_S1AP_Reset(reset_cause, reset_type));
919 T.start;
920 alt {
921 [] S1AP_UNIT[0].receive(tr_S1AP_ResetAck_any) {
922 setverdict(pass);
923 }
924 [] S1AP_UNIT[0].receive {
925 setverdict(fail, "Received unexpected S1AP");
926 }
927 [] T.timeout {
928 setverdict(fail, "Timeout waiting for S1AP Setup result");
929 }
930 }
931}
932
Harald Welte95333a12019-07-11 22:51:45 +0800933control {
934 execute( TC_s1ap_setup_wrong_plmn() );
935 execute( TC_s1ap_setup_wrong_tac() );
936 execute( TC_s1ap_setup() );
Harald Welte6ec64392019-08-14 12:37:07 +0200937 execute( TC_s1ap_attach() );
Philipp Maier74d776a2023-07-12 14:04:14 +0200938 execute( TC_gn_echo_request() );
Philipp Maiera9306202023-07-24 11:41:51 +0200939 execute( TC_RIM_RAN_INF() );
Philipp Maier46059f02023-08-16 14:45:27 +0200940 execute( TC_s1ap_reset() );
Harald Welteb8a4ac82019-06-23 11:04:12 +0200941}
942
Philipp Maier46059f02023-08-16 14:45:27 +0200943
Harald Welteb8a4ac82019-06-23 11:04:12 +0200944}