pespin has uploaded this change for review.

View Change

Split GTPv1U out of GTPv2_Emulation

GTPv1U and GTPv2C are 2 different protocols, working on 2 different
ports, on 2 different sockets.
Hence, it makes no sense to put them together, since some tests may want
to use only the control-plane, others may want to use the user-plane,
etc.
Morevoer, GTPv1U can be used together with both GTPv2C anf GTPv1C.

This commit also fixes the confusion where TEIC and TEID were not
properly separated in GTPv2_Emulation.

Change-Id: Ia45307107753294c6761cb588f0ab769821eb213
---
M epdg/EPDG_Tests.ttcn
M epdg/gen_links.sh
A library/GTPv1U_Emulation.ttcn
M library/GTPv2_Emulation.ttcn
M mme/MME_Tests.ttcn
M mme/gen_links.sh
M mme/regen_makefile.sh
M pgw/PGW_Tests.cfg
M pgw/PGW_Tests.ttcn
M pgw/gen_links.sh
10 files changed, 500 insertions(+), 262 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/44/40744/1
diff --git a/epdg/EPDG_Tests.ttcn b/epdg/EPDG_Tests.ttcn
index 61476e2..f67fc2c 100644
--- a/epdg/EPDG_Tests.ttcn
+++ b/epdg/EPDG_Tests.ttcn
@@ -24,9 +24,10 @@
import from DIAMETER_ts29_273_Templates all;
import from DIAMETER_Emulation all;

-import from GTPv1U_CodecPort all;
import from GTPU_Types all;
+import from GTPv1U_CodecPort all;
import from GTPv1U_Templates all;
+import from GTPv1U_Emulation all;

import from GTPv2_Types all;
import from GTPv2_Templates all;
@@ -90,7 +91,10 @@
port IPA_CTRL_PT GSUP_IPA_EVENT;

var GTPv2_Emulation_CT vc_GTP2;
- port GTP2EM_PT TEID0;
+ port GTP2EM_PT TEIC0;
+
+ var GTPv1U_Emulation_CT vc_GTP1U;
+ port GTP1UEM_PT TEID0;

port Coord_PT COORD;

@@ -133,7 +137,7 @@
}
}

-type component EPDG_ConnHdlr extends DIAMETER_ConnHdlr, GSUP_ConnHdlr, GTP2_ConnHdlr {
+type component EPDG_ConnHdlr extends DIAMETER_ConnHdlr, GSUP_ConnHdlr, GTP2_ConnHdlr, GTP1U_ConnHdlr {
var EPDG_ConnHdlrPars g_pars;

port DIAMETER_Conn_PT SWx;
@@ -298,22 +302,32 @@
f_sleep(int2float(mp_diam_watchdog_initial_wait_sec));
}

-private function f_init_gtp(charstring id) runs on MTC_CT {
+private function f_init_gtp2c(charstring id) runs on MTC_CT {
var Gtp2EmulationCfg cfg := {
gtpc_bind_ip := mp_s2b_local_ip,
gtpc_bind_port := mp_s2b_local_port,
gtpc_remote_ip := mp_s2b_remote_ip,
gtpc_remote_port := mp_s2b_remote_port,
+ sgw_role := false
+ };
+
+ vc_GTP2 := GTPv2_Emulation_CT.create(id & "-GTPv2C");
+ map(vc_GTP2:GTP2C, system:GTP2C);
+ connect(vc_GTP2:TEIC0, self:TEIC0);
+ vc_GTP2.start(GTPv2_Emulation.main(cfg));
+}
+
+private function f_init_gtp1u(charstring id) runs on MTC_CT {
+ var Gtp1uEmulationCfg cfg := {
gtpu_bind_ip := mp_upf_gtpu_local_ip,
gtpu_bind_port := GTP1U_PORT,
- sgw_role := false,
use_gtpu_daemon := false /* TODO: maybe use, set to true */
};

- vc_GTP2 := GTPv2_Emulation_CT.create(id & "-GTPV2");
- map(vc_GTP2:GTP2C, system:GTP2C);
- connect(vc_GTP2:TEID0, self:TEID0);
- vc_GTP2.start(GTPv2_Emulation.main(cfg));
+ vc_GTP1U := GTPv1U_Emulation_CT.create(id & "-GTPv1U");
+ map(vc_GTP1U:GTP1U, system:GTP1U);
+ connect(vc_GTP1U:TEID0, self:TEID0);
+ vc_GTP1U.start(GTPv1U_Emulation.main(cfg));
}

private function f_init(float t_guard := 40.0) runs on MTC_CT {
@@ -323,7 +337,8 @@

f_init_gsup(testcasename());
f_init_diameter(testcasename());
- f_init_gtp(testcasename());
+ f_init_gtp2c(testcasename());
+ f_init_gtp1u(testcasename());
}

private type function void_fn(charstring id) runs on EPDG_ConnHdlr;
@@ -352,9 +367,12 @@
connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);

- /* GTP2 */
+ /* GTP2C */
connect(vc_conn:GTP2, vc_GTP2:CLIENT);
connect(vc_conn:GTP2_PROC, vc_GTP2:CLIENT_PROC);
+ /* GTP1U */
+ connect(vc_conn:GTP1U, vc_GTP1U:CLIENT);
+ connect(vc_conn:GTP1U_PROC, vc_GTP1U:CLIENT_PROC);

/* SWx */
vc_conn_swx := DIAMETER_ConnHdlr_CT.create(id);
@@ -704,8 +722,8 @@
}*/

/* allocate + register TEID-C on local side */
- g_pars.teic_local := f_gtp2_allocate_teid();
- g_pars.bearer.teid_local := g_pars.teic_local;
+ g_pars.teic_local := f_gtp2_allocate_teic();
+ g_pars.bearer.teid_local := f_gtp1u_allocate_teid();
}

/* ePDG Creates session at the PGW. PGW sends Diameter s6b AAR + AAA. */
@@ -862,18 +880,18 @@
}
private function f_GTP1U_send(octetstring payload) runs on EPDG_ConnHdlr {
var Gtp1uPeer peer := valueof(ts_GtpPeerU(f_inet_addr(g_pars.bearer.gtpu_addr_remote)));
- GTP2.send(ts_GTP1U_GPDU(peer, omit /*opt_part*/, g_pars.bearer.teid_remote, payload));
+ GTP1U.send(ts_GTP1U_GPDU(peer, omit /*opt_part*/, g_pars.bearer.teid_remote, payload));
}
private function f_GTP1U_echo_ping_pong(uint16_t seq_nr := 0) runs on EPDG_ConnHdlr {
var Gtp1uPeer peer := valueof(ts_GtpPeerU(f_inet_addr(g_pars.bearer.gtpu_addr_remote)));
- GTP2.send(ts_GTPU_PING(peer, seq := seq_nr));
- GTP2.receive(tr_GTPU_PONG(peer));
+ GTP1U.send(ts_GTPU_PING(peer, seq := seq_nr));
+ GTP1U.receive(tr_GTPU_PONG(peer));
}
private altstep as_GTPU_rx_icmp4(template (present) PDU_ICMP expected := ?) runs on EPDG_ConnHdlr {
var Gtp1uUnitdata rx_msg;
var template (value) Gtp1uPeer peer := ts_GtpPeerU(f_inet_addr(g_pars.bearer.gtpu_addr_remote));

- [] GTP2.receive(tr_GTPU_GPDU(peer, g_pars.bearer.teid_local)) -> value rx_msg {
+ [] GTP1U.receive(tr_GTPU_GPDU(peer, g_pars.bearer.teid_local)) -> value rx_msg {
/*TODO: verify gtpu txseq:
if (f_verify_gtpu_txseq(ud.gtpu, use_gtpu_txseq) == false) {
setverdict(fail);
@@ -890,7 +908,7 @@
repeat;
}
}
- [] GTP2.receive(Gtp1uUnitdata:?) -> value rx_msg {
+ [] GTP1U.receive(Gtp1uUnitdata:?) -> value rx_msg {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GTP msg rx: ", rx_msg));
}
}
@@ -1298,7 +1316,7 @@
private function f_TC_upf_echo_req(charstring id) runs on EPDG_ConnHdlr {
f_initial_attach();
/* Dispatch Echo Resp to this component: */
- f_gtp2_register_teid('00000000'O);
+ f_gtp1u_register_teid('00000000'O);
f_GTP1U_echo_ping_pong(seq_nr := 0);
/* Send one again, to validate it works several times: */
f_GTP1U_echo_ping_pong(seq_nr := 1);
@@ -1316,7 +1334,7 @@
private function f_TC_mt_ipv4_echo_req(charstring id) runs on EPDG_ConnHdlr {
f_initial_attach();
/* Dispatch Echo Resp to this component: */
- f_gtp2_register_teid('00000000'O);
+ f_gtp1u_register_teid('00000000'O);
var octetstring echo_req := f_gen_icmpv4_echo(f_inet_addr(mp_upf_gtpu_local_ip), f_inet_addr(g_pars.ue_ip));
f_GTP1U_send(echo_req);
as_GTPU_rx_icmp4((tr_ICMPv4_ERP, tr_ICMPv4_DU));
diff --git a/epdg/gen_links.sh b/epdg/gen_links.sh
index 889cb9a..d41e2e1 100755
--- a/epdg/gen_links.sh
+++ b/epdg/gen_links.sh
@@ -59,7 +59,7 @@
FILES+="IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc
IPA_Emulation.ttcnpp "
FILES+="PCO_Types.ttcn GSUP_Types.ttcn GSUP_Templates.ttcn GSUP_Emulation.ttcn "
-FILES+="GTPv1U_CodecPort.ttcn GTPv1U_CodecPort_CtrlFunct.ttcn GTPv1U_CodecPort_CtrlFunctDef.cc GTPv1U_Templates.ttcn "
+FILES+="GTPv1U_CodecPort.ttcn GTPv1U_CodecPort_CtrlFunct.ttcn GTPv1U_CodecPort_CtrlFunctDef.cc GTPv1U_Templates.ttcn GTPv1U_Emulation.ttcn "
FILES+="GTPv2_PrivateExtensions.ttcn GTPv2_Templates.ttcn "
FILES+="GTPv2_CodecPort.ttcn GTPv2_CodecPort_CtrlFunctDef.cc GTPv2_CodecPort_CtrlFunct.ttcn GTPv2_Emulation.ttcn "
FILES+="ICMP_Templates.ttcn "
diff --git a/library/GTPv1U_Emulation.ttcn b/library/GTPv1U_Emulation.ttcn
new file mode 100644
index 0000000..7c031b7
--- /dev/null
+++ b/library/GTPv1U_Emulation.ttcn
@@ -0,0 +1,361 @@
+/* GTPv1U Emulation in TTCN-3
+ *
+ * (C) 2018-2020 Harald Welte <laforge@gnumonks.org>
+ * (C) 2025 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All rights reserved.
+ *
+ * Released under the terms of GNU General Public License, Version 2 or
+ * (at your option) any later version.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+module GTPv1U_Emulation {
+
+import from IPL4asp_Types all;
+import from General_Types all;
+import from Osmocom_Types all;
+import from GTPU_Types all;
+import from GTPv1U_CodecPort all;
+import from GTPv1U_CodecPort_CtrlFunct all;
+
+import from SCTP_Templates all;
+import from UECUPS_Types all;
+import from UECUPS_CodecPort all;
+import from UECUPS_CodecPort_CtrlFunct all;
+
+/***********************************************************************
+ * Main Emulation Component
+ ***********************************************************************/
+
+modulepar {
+ charstring mp_uecups_host := "127.0.0.1";
+ integer mp_uecups_port := UECUPS_SCTP_PORT;
+};
+
+const integer GTP1U_PORT := 2152;
+
+type record Gtp1uEmulationCfg {
+ HostName gtpu_bind_ip optional,
+ IPL4asp_Types.PortNumber gtpu_bind_port optional,
+ boolean use_gtpu_daemon
+};
+
+type component GTPv1U_Emulation_CT {
+ /* Communication with underlying GTP CodecPort */
+ port GTPU_PT GTP1U;
+
+ /* Control port to GTP-U Daemon */
+ port UECUPS_CODEC_PT UECUPS;
+
+ /* Communication with Clients */
+ port GTP1UEM_PT TEID0;
+ port GTP1UEM_PT CLIENT;
+ port GTP1UEM_PROC_PT CLIENT_PROC;
+
+ /* Configuration by the user */
+ var Gtp1uEmulationCfg g_gtp1u_cfg;
+
+ /* State */
+ var integer g_gtp1u_id := -1;
+ var OCT1 g_restart_ctr;
+ var uint16_t g_c_seq_nr;
+ var TidTableRec TidTable[256];
+ var PidTableRec PidTable[256];
+
+ var integer g_uecups_conn_id := -1;
+};
+
+/* local TEID <-> ConnHdlr mapping */
+type record TidTableRec {
+ OCT4 teid,
+ GTP1U_ConnHdlr vc_conn
+};
+
+/* pid <-> ConnHdlr mapping (for UECUPS process termination indication) */
+type record PidTableRec {
+ /* process ID of the running process */
+ integer pid,
+ /* component that started it */
+ GTP1U_ConnHdlr vc_conn
+};
+
+private function f_teid_known(OCT4 teid) runs on GTPv1U_Emulation_CT return boolean {
+ var integer i;
+ for (i := 0; i < sizeof(TidTable); i := i+1) {
+ if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) {
+ return true;
+ }
+ }
+ return false;
+}
+
+private function f_comp_by_teid(OCT4 teid) runs on GTPv1U_Emulation_CT return GTP1U_ConnHdlr {
+ var integer i;
+ for (i := 0; i < sizeof(TidTable); i := i+1) {
+ if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) {
+ return TidTable[i].vc_conn;
+ }
+ }
+ setverdict(fail, "No Component for TEID ", teid);
+ mtc.stop;
+}
+
+private function f_comp_by_pid(integer pid) runs on GTPv1U_Emulation_CT return GTP1U_ConnHdlr {
+ var integer i;
+ for (i := 0; i < sizeof(PidTable); i := i+1) {
+ if (isbound(PidTable[i].pid) and PidTable[i].pid == pid) {
+ /* fixme: remove */
+ return PidTable[i].vc_conn;
+ }
+ }
+ setverdict(fail, "No Component for PID ", pid);
+ mtc.stop;
+}
+
+private function f_tid_tbl_add(OCT4 teid, GTP1U_ConnHdlr vc_conn) runs on GTPv1U_Emulation_CT {
+ var integer i;
+ for (i := 0; i < sizeof(TidTable); i := i+1) {
+ if (not isbound(TidTable[i].teid)) {
+ TidTable[i].teid := teid;
+ TidTable[i].vc_conn := vc_conn;
+ return;
+ }
+ }
+ testcase.stop("No Space in TidTable for ", teid);
+}
+
+private function f_pid_tbl_add(integer pid, GTP1U_ConnHdlr vc_conn) runs on GTPv1U_Emulation_CT {
+ var integer i;
+ for (i := 0; i < sizeof(PidTable); i := i+1) {
+ if (not isbound(PidTable[i].pid)) {
+ PidTable[i].pid := pid;
+ PidTable[i].vc_conn := vc_conn;
+ return;
+ }
+ }
+ testcase.stop("No Space in PID Table for ", pid);
+}
+
+
+/* allocate an unused local teid */
+private function f_alloc_teid() runs on GTPv1U_Emulation_CT return OCT4 {
+ var OCT4 teid;
+ var integer i, j;
+ for (i := 0; i < 100; i := i+1) {
+ teid := f_rnd_octstring(4);
+ for (j := 0; j < sizeof(TidTable); j := j+1) {
+ if (isbound(TidTable) and TidTable[i].teid == teid) {
+ continue;
+ }
+ }
+ /* we iterated over all entries and found no match: great! */
+ return teid;
+ }
+ testcase.stop("Cannot find unused TEID after ", i, " attempts");
+}
+
+function tr_UECUPS_RecvFrom_R(template PDU_UECUPS msg)
+runs on GTPv1U_Emulation_CT return template UECUPS_RecvFrom {
+ var template UECUPS_RecvFrom mrf := {
+ connId := g_uecups_conn_id,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ msg := msg
+ }
+ return mrf;
+}
+
+
+private function f_uecups_xceive(template (value) PDU_UECUPS tx,
+ template PDU_UECUPS rx_t := ?, float time_out := 10.0)
+runs on GTPv1U_Emulation_CT return PDU_UECUPS {
+ timer T := time_out;
+ var UECUPS_RecvFrom mrf;
+
+ UECUPS.send(t_UECUPS_Send(g_uecups_conn_id, tx));
+ T.start;
+ alt {
+ [] UECUPS.receive(tr_UECUPS_RecvFrom_R(rx_t)) -> value mrf { }
+ [] UECUPS.receive(tr_SctpAssocChange) { repeat; }
+ [] UECUPS.receive(tr_SctpPeerAddrChange) { repeat; }
+ [] T.timeout {
+ setverdict(fail, "Timeout waiting for ", rx_t);
+ mtc.stop;
+ }
+ }
+ return mrf.msg;
+}
+
+private function f_init(Gtp1uEmulationCfg cfg) runs on GTPv1U_Emulation_CT {
+ var Result res;
+
+ g_restart_ctr := f_rnd_octstring(1);
+ g_c_seq_nr := f_rnd_int(65535);
+ g_gtp1u_cfg := cfg;
+
+ if (g_gtp1u_cfg.use_gtpu_daemon) {
+ map(self:UECUPS, system:UECUPS);
+ res := UECUPS_CodecPort_CtrlFunct.f_IPL4_connect(UECUPS, mp_uecups_host, mp_uecups_port, "", -1, -1,
+ { sctp := valueof(ts_SctpTuple) });
+ if (not ispresent(res.connId)) {
+ setverdict(fail, "Could not connect UECUPS socket, check your configuration");
+ testcase.stop;
+ }
+ g_uecups_conn_id := res.connId;
+ /* clear all tunnel state in the daemon at start */
+ f_uecups_xceive({reset_all_state := {}}, {reset_all_state_res:=?}, 30.0);
+ /* make sure we always pass incoming UECUPS indications whenever receiving fom the UECUPS port */
+ activate(as_uecups_ind());
+ } else if (isvalue(cfg.gtpu_bind_ip) and isvalue(cfg.gtpu_bind_port)) {
+ map(self:GTP1U, system:GTP1U);
+ res := GTPv1U_CodecPort_CtrlFunct.f_GTPU_listen(GTP1U, cfg.gtpu_bind_ip,
+ cfg.gtpu_bind_port, {udp:={}});
+ g_gtp1u_id := res.connId;
+ }
+}
+
+private altstep as_uecups_ind() runs on GTPv1U_Emulation_CT {
+var UECUPS_RecvFrom rx;
+var GTP1U_ConnHdlr vc_conn;
+/* handle incoming program_term_ind; dispatch to whatever component started the process */
+[] UECUPS.receive(tr_UECUPS_RecvFrom_R({program_term_ind:=?})) -> value rx {
+ vc_conn := f_comp_by_pid(rx.msg.program_term_ind.pid);
+ CLIENT.send(rx.msg.program_term_ind) to vc_conn;
+ /* FIXME: remove from table */
+ repeat;
+ }
+}
+
+function main(Gtp1uEmulationCfg cfg) runs on GTPv1U_Emulation_CT {
+ var Gtp1uUnitdata g1u_ud;
+ var GTP1U_ConnHdlr vc_conn;
+ var OCT4 teid;
+ var PDU_UECUPS rx_uecups;
+ var UECUPS_CreateTun gtc;
+ var UECUPS_DestroyTun gtd;
+ var UECUPS_StartProgram sprog;
+
+ f_init(cfg);
+
+ while (true) {
+ alt {
+ [] GTP1U.receive(Gtp1uUnitdata:?) -> value g1u_ud {
+ if (f_teid_known(g1u_ud.gtpu.teid)) {
+ vc_conn := f_comp_by_teid(g1u_ud.gtpu.teid);
+ CLIENT.send(g1u_ud) to vc_conn;
+ } else if (g1u_ud.gtpu.teid == '00000000'O) {
+ TEID0.send(g1u_ud);
+ } else {
+ log("No client registered for TEID=", g1u_ud.gtpu.teid, "!");
+ }
+ }
+ [] TEID0.receive(Gtp1uUnitdata:?) -> value g1u_ud sender vc_conn {
+ GTP1U.send(g1u_ud);
+ }
+ [] CLIENT.receive(Gtp1uUnitdata:?) -> value g1u_ud sender vc_conn {
+ GTP1U.send(g1u_ud);
+ }
+
+ [] CLIENT_PROC.getcall(GTP1UEM_register_teid:{?}) -> param(teid) sender vc_conn {
+ f_tid_tbl_add(teid, vc_conn);
+ CLIENT_PROC.reply(GTP1UEM_register_teid:{teid}) to vc_conn;
+ }
+ [] CLIENT_PROC.getcall(GTP1UEM_allocate_teid:{}) -> sender vc_conn {
+ var OCT4 t := f_alloc_teid();
+ f_tid_tbl_add(t, vc_conn);
+ CLIENT_PROC.reply(GTP1UEM_allocate_teid:{} value t) to vc_conn;
+ }
+ [] CLIENT_PROC.getcall(GTP1UEM_create_tunnel:{?}) -> param(gtc) sender vc_conn {
+ rx_uecups := f_uecups_xceive({create_tun := gtc}, {create_tun_res:={result:=OK}});
+ CLIENT_PROC.reply(GTP1UEM_create_tunnel:{gtc}) to vc_conn;
+ }
+ [] CLIENT_PROC.getcall(GTP1UEM_destroy_tunnel:{?}) -> param(gtd) sender vc_conn {
+ rx_uecups := f_uecups_xceive({destroy_tun := gtd}, {destroy_tun_res:={result:=OK}});
+ CLIENT_PROC.reply(GTP1UEM_destroy_tunnel:{gtd}) to vc_conn;
+ }
+ [] CLIENT_PROC.getcall(GTP1UEM_start_program:{?}) -> param(sprog) sender vc_conn {
+ rx_uecups := f_uecups_xceive({start_program := sprog}, {start_program_res:=?});
+ /* if successful: store (pid, vc_conn) tuple so we can route program_term_ind */
+ if (rx_uecups.start_program_res.result == OK) {
+ f_pid_tbl_add(rx_uecups.start_program_res.pid, vc_conn);
+ }
+ CLIENT_PROC.reply(GTP1UEM_start_program:{sprog} value rx_uecups.start_program_res) to vc_conn;
+ }
+
+ }
+ }
+}
+
+
+/***********************************************************************
+ * Interaction between Main and Client Components
+ ***********************************************************************/
+type port GTP1UEM_PT message {
+ inout Gtp1uUnitdata, UECUPS_ProgramTermInd;
+} with { extension "internal" };
+
+signature GTP1UEM_register_teid(OCT4 teid);
+signature GTP1UEM_allocate_teid() return OCT4;
+signature GTP1UEM_create_tunnel(UECUPS_CreateTun gtc);
+signature GTP1UEM_destroy_tunnel(UECUPS_DestroyTun gtd);
+signature GTP1UEM_start_program(UECUPS_StartProgram sprog) return UECUPS_StartProgramRes;
+
+type port GTP1UEM_PROC_PT procedure {
+ inout GTP1UEM_register_teid, GTP1UEM_allocate_teid,
+ GTP1UEM_create_tunnel, GTP1UEM_destroy_tunnel, GTP1UEM_start_program;
+} with { extension "internal" };
+
+/***********************************************************************
+ * Client Component
+ ***********************************************************************/
+
+type component GTP1U_ConnHdlr {
+ port GTP1UEM_PT GTP1U;
+ port GTP1UEM_PROC_PT GTP1U_PROC;
+};
+
+
+function f_gtp1u_register_teid(OCT4 teid) runs on GTP1U_ConnHdlr {
+ GTP1U_PROC.call(GTP1UEM_register_teid:{teid}) {
+ [] GTP1U_PROC.getreply(GTP1UEM_register_teid:{teid});
+ }
+}
+
+function f_gtp1u_allocate_teid() runs on GTP1U_ConnHdlr return OCT4 {
+ var OCT4 t;
+ GTP1U_PROC.call(GTP1UEM_allocate_teid:{}) {
+ [] GTP1U_PROC.getreply(GTP1UEM_allocate_teid:{}) -> value t {
+ return t;
+ }
+ }
+}
+
+function f_gtp1u_create_tunnel(template (value) UECUPS_CreateTun gtc)
+runs on GTP1U_ConnHdlr {
+ GTP1U_PROC.call(GTP1UEM_create_tunnel:{valueof(gtc)}) {
+ [] GTP1U_PROC.getreply(GTP1UEM_create_tunnel:{gtc});
+ }
+}
+
+function f_gtp1u_destroy_tunnel(template (value) UECUPS_DestroyTun gtd)
+runs on GTP1U_ConnHdlr {
+ GTP1U_PROC.call(GTP1UEM_destroy_tunnel:{valueof(gtd)}) {
+ [] GTP1U_PROC.getreply(GTP1UEM_destroy_tunnel:{gtd});
+ }
+}
+
+function f_gtp1u_start_program(template (value) UECUPS_StartProgram sprog)
+runs on GTP1U_ConnHdlr return UECUPS_StartProgramRes {
+ var UECUPS_StartProgramRes res;
+ GTP1U_PROC.call(GTP1UEM_start_program:{valueof(sprog)}) {
+ [] GTP1U_PROC.getreply(GTP1UEM_start_program:{sprog}) -> value res;
+ }
+ return res;
+}
+
+
+
+}
diff --git a/library/GTPv2_Emulation.ttcn b/library/GTPv2_Emulation.ttcn
index 15720f9..7ef5283 100644
--- a/library/GTPv2_Emulation.ttcn
+++ b/library/GTPv2_Emulation.ttcn
@@ -14,52 +14,33 @@
import from IPL4asp_Types all;
import from General_Types all;
import from Osmocom_Types all;
-import from GTPU_Types all;
-import from GTPv1U_CodecPort all;
-import from GTPv1U_CodecPort_CtrlFunct all;
import from GTPv2_Types all;
import from GTPv2_Templates all;
import from GTPv2_CodecPort all;
import from GTPv2_CodecPort_CtrlFunct all;
-import from SCTP_Templates all;
-
-import from UECUPS_Types all;
-import from UECUPS_CodecPort all;
-import from UECUPS_CodecPort_CtrlFunct all;

/***********************************************************************
* Main Emulation Component
***********************************************************************/

-modulepar {
- charstring mp_uecups_host := "127.0.0.1";
- integer mp_uecups_port := UECUPS_SCTP_PORT;
-};
+//modulepar {};

const integer GTP2C_PORT := 2123;
-const integer GTP1U_PORT := 2152;

type record Gtp2EmulationCfg {
HostName gtpc_bind_ip,
IPL4asp_Types.PortNumber gtpc_bind_port,
HostName gtpc_remote_ip,
IPL4asp_Types.PortNumber gtpc_remote_port,
- HostName gtpu_bind_ip optional,
- IPL4asp_Types.PortNumber gtpu_bind_port optional,
- boolean sgw_role,
- boolean use_gtpu_daemon
+ boolean sgw_role
};

type component GTPv2_Emulation_CT {
/* Communication with underlying GTP CodecPort */
port GTPv2C_PT GTP2C;
- port GTPU_PT GTPU;
-
- /* Control port to GTP-U Daemon */
- port UECUPS_CODEC_PT UECUPS;

/* Communication with Clients */
- port GTP2EM_PT TEID0;
+ port GTP2EM_PT TEIC0;
port GTP2EM_PT CLIENT;
port GTP2EM_PROC_PT CLIENT_PROC;

@@ -68,7 +49,7 @@

/* State */
var Gtp2cPeer g_peer;
- var integer g_gtp2c_id, g_gtp1u_id;
+ var integer g_gtp2c_id;
var OCT1 g_restart_ctr;
var uint16_t g_c_seq_nr;
var TidTableRec TidTable[256];
@@ -76,13 +57,11 @@
var ImsiTableRec ImsiTable[256];
var UdMsgTableRec UdMsgTable[256];
var PidTableRec PidTable[256];
-
- var integer g_uecups_conn_id;
};

-/* local TEID <-> ConnHdlr mapping */
+/* local TEIC <-> ConnHdlr mapping */
type record TidTableRec {
- OCT4 teid,
+ OCT4 teic,
GTP2_ConnHdlr vc_conn
};

@@ -112,24 +91,24 @@
GTP2_ConnHdlr vc_conn
};

-private function f_teid_known(OCT4 teid) runs on GTPv2_Emulation_CT return boolean {
+private function f_teic_known(OCT4 teic) runs on GTPv2_Emulation_CT return boolean {
var integer i;
for (i := 0; i < sizeof(TidTable); i := i+1) {
- if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) {
+ if (isbound(TidTable[i].teic) and TidTable[i].teic == teic) {
return true;
}
}
return false;
}

-private function f_comp_by_teid(OCT4 teid) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr {
+private function f_comp_by_teic(OCT4 teic) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr {
var integer i;
for (i := 0; i < sizeof(TidTable); i := i+1) {
- if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) {
+ if (isbound(TidTable[i].teic) and TidTable[i].teic == teic) {
return TidTable[i].vc_conn;
}
}
- setverdict(fail, "No Component for TEID ", teid);
+ setverdict(fail, "No Component for TEIC ", teic);
mtc.stop;
}

@@ -187,16 +166,16 @@
mtc.stop;
}

-private function f_tid_tbl_add(OCT4 teid, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
+private function f_tid_tbl_add(OCT4 teic, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
var integer i;
for (i := 0; i < sizeof(TidTable); i := i+1) {
- if (not isbound(TidTable[i].teid)) {
- TidTable[i].teid := teid;
+ if (not isbound(TidTable[i].teic)) {
+ TidTable[i].teic := teic;
TidTable[i].vc_conn := vc_conn;
return;
}
}
- testcase.stop("No Space in TidTable for ", teid);
+ testcase.stop("No Space in TidTable for ", teic);
}

private function f_seq_tbl_add(OCT3 seq, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
@@ -260,21 +239,21 @@
}


-/* allocate an unused local teid */
-private function f_alloc_teid() runs on GTPv2_Emulation_CT return OCT4 {
- var OCT4 teid;
+/* allocate an unused local teic */
+private function f_alloc_teic() runs on GTPv2_Emulation_CT return OCT4 {
+ var OCT4 teic;
var integer i, j;
for (i := 0; i < 100; i := i+1) {
- teid := f_rnd_octstring(4);
+ teic := f_rnd_octstring(4);
for (j := 0; j < sizeof(TidTable); j := j+1) {
- if (isbound(TidTable) and TidTable[i].teid == teid) {
+ if (isbound(TidTable) and TidTable[i].teic == teic) {
continue;
}
}
/* we iterated over all entries and found no match: great! */
- return teid;
+ return teic;
}
- testcase.stop("Cannot find unused TEID after ", i, " attempts");
+ testcase.stop("Cannot find unused TEIC after ", i, " attempts");
}

/* obtain the IMSI from a GTPv2C PDU, if there is any IMSI contained. The way how the TITAN
@@ -432,40 +411,6 @@
return false;
}

-function tr_UECUPS_RecvFrom_R(template PDU_UECUPS msg)
-runs on GTPv2_Emulation_CT return template UECUPS_RecvFrom {
- var template UECUPS_RecvFrom mrf := {
- connId := g_uecups_conn_id,
- remName := ?,
- remPort := ?,
- locName := ?,
- locPort := ?,
- msg := msg
- }
- return mrf;
-}
-
-
-private function f_uecups_xceive(template (value) PDU_UECUPS tx,
- template PDU_UECUPS rx_t := ?, float time_out := 10.0)
-runs on GTPv2_Emulation_CT return PDU_UECUPS {
- timer T := time_out;
- var UECUPS_RecvFrom mrf;
-
- UECUPS.send(t_UECUPS_Send(g_uecups_conn_id, tx));
- T.start;
- alt {
- [] UECUPS.receive(tr_UECUPS_RecvFrom_R(rx_t)) -> value mrf { }
- [] UECUPS.receive(tr_SctpAssocChange) { repeat; }
- [] UECUPS.receive(tr_SctpPeerAddrChange) { repeat; }
- [] T.timeout {
- setverdict(fail, "Timeout waiting for ", rx_t);
- mtc.stop;
- }
- }
- return mrf.msg;
-}
-
private function f_init(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT {
var Result res;

@@ -482,41 +427,6 @@
remName := g_gtp2_cfg.gtpc_remote_ip,
remPort := g_gtp2_cfg.gtpc_remote_port
}
-
- g_uecups_conn_id := res.connId;
-
- if (g_gtp2_cfg.use_gtpu_daemon) {
- map(self:UECUPS, system:UECUPS);
- res := UECUPS_CodecPort_CtrlFunct.f_IPL4_connect(UECUPS, mp_uecups_host, mp_uecups_port, "", -1, -1,
- { sctp := valueof(ts_SctpTuple) });
- if (not ispresent(res.connId)) {
- setverdict(fail, "Could not connect UECUPS socket, check your configuration");
- testcase.stop;
- }
-
- /* clear all tunnel state in the daemon at start */
- f_uecups_xceive({reset_all_state := {}}, {reset_all_state_res:=?}, 30.0);
- } else if (isvalue(cfg.gtpu_bind_ip) and isvalue(cfg.gtpu_bind_port)) {
- map(self:GTPU, system:GTPU);
- res := GTPv1U_CodecPort_CtrlFunct.f_GTPU_listen(GTPU, cfg.gtpu_bind_ip,
- cfg.gtpu_bind_port, {udp:={}});
- g_gtp1u_id := res.connId;
- }
-
- /* make sure we always pass incoming UECUPS indications whenever receiving fom the UECUPS port */
- activate(as_uecups_ind());
-}
-
-private altstep as_uecups_ind() runs on GTPv2_Emulation_CT {
-var UECUPS_RecvFrom rx;
-var GTP2_ConnHdlr vc_conn;
-/* handle incoming program_term_ind; dispatch to whatever component started the process */
-[] UECUPS.receive(tr_UECUPS_RecvFrom_R({program_term_ind:=?})) -> value rx {
- vc_conn := f_comp_by_pid(rx.msg.program_term_ind.pid);
- CLIENT.send(rx.msg.program_term_ind) to vc_conn;
- /* FIXME: remove from table */
- repeat;
- }
}

private function SendToUdMsgTable(Gtp2cUnitdata g2c_ud) runs on GTPv2_Emulation_CT {
@@ -536,22 +446,17 @@

function main(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT {
var Gtp2cUnitdata g2c_ud;
- var Gtp1uUnitdata g1u_ud;
var PDU_GTPCv2 g2c;
var GTP2_ConnHdlr vc_conn;
var hexstring imsi;
var OCT1 messageType;
- var OCT4 teid;
- var PDU_UECUPS rx_uecups;
- var UECUPS_CreateTun gtc;
- var UECUPS_DestroyTun gtd;
- var UECUPS_StartProgram sprog;
+ var OCT4 teic;

f_init(cfg);

while (true) {
alt {
- /* route inbound GTP2-C based on TEID, SEQ or IMSI */
+ /* route inbound GTP2-C based on TEIC, SEQ or IMSI */
[] GTP2C.receive(Gtp2cUnitdata:?) -> value g2c_ud {
var template hexstring imsi_t := f_gtp2c_extract_imsi(g2c_ud.gtpc);
/* if this is a response, route by SEQ: */
@@ -563,17 +468,17 @@
vc_conn := f_comp_by_imsi(valueof(imsi_t));
CLIENT.send(g2c_ud.gtpc) to vc_conn;
} else if ((ispresent(g2c_ud.gtpc.tEID) and g2c_ud.gtpc.tEID != '00000000'O)
- and f_teid_known(g2c_ud.gtpc.tEID)) {
- vc_conn := f_comp_by_teid(g2c_ud.gtpc.tEID);
+ and f_teic_known(g2c_ud.gtpc.tEID)) {
+ vc_conn := f_comp_by_teic(g2c_ud.gtpc.tEID);
CLIENT.send(g2c_ud.gtpc) to vc_conn;
} else if ((not ispresent(g2c_ud.gtpc.tEID) or g2c_ud.gtpc.tEID == '00000000'O)
- and f_teid_known('00000000'O)) {
- vc_conn := f_comp_by_teid(g2c_ud.gtpc.tEID);
+ and f_teic_known('00000000'O)) {
+ vc_conn := f_comp_by_teic(g2c_ud.gtpc.tEID);
CLIENT.send(g2c_ud.gtpc) to vc_conn;
} else {
SendToUdMsgTable(g2c_ud);
if (not ispresent(g2c_ud.gtpc.tEID) or g2c_ud.gtpc.tEID == '00000000'O) {
- TEID0.send(g2c_ud.gtpc);
+ TEIC0.send(g2c_ud.gtpc);
}
}

@@ -583,18 +488,8 @@
}

}
- [] GTPU.receive(Gtp1uUnitdata:?) -> value g1u_ud {
- if (f_teid_known(g1u_ud.gtpu.teid)) {
- vc_conn := f_comp_by_teid(g1u_ud.gtpu.teid);
- CLIENT.send(g1u_ud) to vc_conn;
- } else if (g1u_ud.gtpu.teid == '00000000'O) {
- TEID0.send(g1u_ud);
- } else {
- log("No client registered for TEID=", g1u_ud.gtpu.teid, "!");
- }
- }

- [] TEID0.receive(PDU_GTPCv2:?) -> value g2c sender vc_conn {
+ [] TEIC0.receive(PDU_GTPCv2:?) -> value g2c sender vc_conn {
/* patch in the next sequence number on outbound Initial message */
if (f_gtp2c_is_initial_msg(g2c)) {
g2c.sequenceNumber := int2oct(g_c_seq_nr, 3);
@@ -607,9 +502,6 @@
f_seq_tbl_add(g2c.sequenceNumber, vc_conn);
}
}
- [] TEID0.receive(Gtp1uUnitdata:?) -> value g1u_ud sender vc_conn {
- GTPU.send(g1u_ud);
- }

[] CLIENT.receive(PDU_GTPCv2:?) -> value g2c sender vc_conn {
/* patch in the next sequence number on outbound Initial message */
@@ -624,9 +516,6 @@
f_seq_tbl_add(g2c.sequenceNumber, vc_conn);
}
}
- [] CLIENT.receive(Gtp1uUnitdata:?) -> value g1u_ud sender vc_conn {
- GTPU.send(g1u_ud);
- }

[] CLIENT_PROC.getcall(GTP2EM_register_imsi:{?}) -> param(imsi) sender vc_conn {
f_imsi_tbl_add(imsi, vc_conn);
@@ -637,32 +526,15 @@
CLIENT_PROC.reply(GTP2EM_register_udmsg:{messageType}) to vc_conn;
}

- [] CLIENT_PROC.getcall(GTP2EM_register_teid:{?}) -> param(teid) sender vc_conn {
- f_tid_tbl_add(teid, vc_conn);
- CLIENT_PROC.reply(GTP2EM_register_teid:{teid}) to vc_conn;
+ [] CLIENT_PROC.getcall(GTP2EM_register_teic:{?}) -> param(teic) sender vc_conn {
+ f_tid_tbl_add(teic, vc_conn);
+ CLIENT_PROC.reply(GTP2EM_register_teic:{teic}) to vc_conn;
}
- [] CLIENT_PROC.getcall(GTP2EM_allocate_teid:{}) -> sender vc_conn {
- var OCT4 t := f_alloc_teid();
+ [] CLIENT_PROC.getcall(GTP2EM_allocate_teic:{}) -> sender vc_conn {
+ var OCT4 t := f_alloc_teic();
f_tid_tbl_add(t, vc_conn);
- CLIENT_PROC.reply(GTP2EM_allocate_teid:{} value t) to vc_conn;
+ CLIENT_PROC.reply(GTP2EM_allocate_teic:{} value t) to vc_conn;
}
- [] CLIENT_PROC.getcall(GTP2EM_create_tunnel:{?}) -> param(gtc) sender vc_conn {
- rx_uecups := f_uecups_xceive({create_tun := gtc}, {create_tun_res:={result:=OK}});
- CLIENT_PROC.reply(GTP2EM_create_tunnel:{gtc}) to vc_conn;
- }
- [] CLIENT_PROC.getcall(GTP2EM_destroy_tunnel:{?}) -> param(gtd) sender vc_conn {
- rx_uecups := f_uecups_xceive({destroy_tun := gtd}, {destroy_tun_res:={result:=OK}});
- CLIENT_PROC.reply(GTP2EM_destroy_tunnel:{gtd}) to vc_conn;
- }
- [] CLIENT_PROC.getcall(GTP2EM_start_program:{?}) -> param(sprog) sender vc_conn {
- rx_uecups := f_uecups_xceive({start_program := sprog}, {start_program_res:=?});
- /* if successful: store (pid, vc_conn) tuple so we can route program_term_ind */
- if (rx_uecups.start_program_res.result == OK) {
- f_pid_tbl_add(rx_uecups.start_program_res.pid, vc_conn);
- }
- CLIENT_PROC.reply(GTP2EM_start_program:{sprog} value rx_uecups.start_program_res) to vc_conn;
- }
-
}
}
}
@@ -672,20 +544,17 @@
* Interaction between Main and Client Components
***********************************************************************/
type port GTP2EM_PT message {
- inout PDU_GTPCv2, Gtp1uUnitdata, UECUPS_ProgramTermInd;
+ inout PDU_GTPCv2;
} with { extension "internal" };

signature GTP2EM_register_imsi(hexstring imsi);
signature GTP2EM_register_udmsg(OCT1 messageType);
-signature GTP2EM_register_teid(OCT4 teid);
-signature GTP2EM_allocate_teid() return OCT4;
-signature GTP2EM_create_tunnel(UECUPS_CreateTun gtc);
-signature GTP2EM_destroy_tunnel(UECUPS_DestroyTun gtd);
-signature GTP2EM_start_program(UECUPS_StartProgram sprog) return UECUPS_StartProgramRes;
+signature GTP2EM_register_teic(OCT4 teic);
+signature GTP2EM_allocate_teic() return OCT4;

type port GTP2EM_PROC_PT procedure {
- inout GTP2EM_register_imsi, GTP2EM_register_udmsg, GTP2EM_register_teid, GTP2EM_allocate_teid,
- GTP2EM_create_tunnel, GTP2EM_destroy_tunnel, GTP2EM_start_program;
+ inout GTP2EM_register_imsi, GTP2EM_register_udmsg,
+ GTP2EM_register_teic, GTP2EM_allocate_teic;
} with { extension "internal" };

/***********************************************************************
@@ -713,44 +582,18 @@
}
}

-function f_gtp2_register_teid(OCT4 teid) runs on GTP2_ConnHdlr {
- GTP2_PROC.call(GTP2EM_register_teid:{teid}) {
- [] GTP2_PROC.getreply(GTP2EM_register_teid:{teid});
+function f_gtp2_register_teic(OCT4 teic) runs on GTP2_ConnHdlr {
+ GTP2_PROC.call(GTP2EM_register_teic:{teic}) {
+ [] GTP2_PROC.getreply(GTP2EM_register_teic:{teic});
}
}

-function f_gtp2_allocate_teid() runs on GTP2_ConnHdlr return OCT4 {
+function f_gtp2_allocate_teic() runs on GTP2_ConnHdlr return OCT4 {
var OCT4 t;
- GTP2_PROC.call(GTP2EM_allocate_teid:{}) {
- [] GTP2_PROC.getreply(GTP2EM_allocate_teid:{}) -> value t {
+ GTP2_PROC.call(GTP2EM_allocate_teic:{}) {
+ [] GTP2_PROC.getreply(GTP2EM_allocate_teic:{}) -> value t {
return t;
}
}
}
-
-function f_gtp2_create_tunnel(template (value) UECUPS_CreateTun gtc)
-runs on GTP2_ConnHdlr {
- GTP2_PROC.call(GTP2EM_create_tunnel:{valueof(gtc)}) {
- [] GTP2_PROC.getreply(GTP2EM_create_tunnel:{gtc});
- }
-}
-
-function f_gtp2_destroy_tunnel(template (value) UECUPS_DestroyTun gtd)
-runs on GTP2_ConnHdlr {
- GTP2_PROC.call(GTP2EM_destroy_tunnel:{valueof(gtd)}) {
- [] GTP2_PROC.getreply(GTP2EM_destroy_tunnel:{gtd});
- }
-}
-
-function f_gtp2_start_program(template (value) UECUPS_StartProgram sprog)
-runs on GTP2_ConnHdlr return UECUPS_StartProgramRes {
- var UECUPS_StartProgramRes res;
- GTP2_PROC.call(GTP2EM_start_program:{valueof(sprog)}) {
- [] GTP2_PROC.getreply(GTP2EM_start_program:{sprog}) -> value res;
- }
- return res;
-}
-
-
-
}
diff --git a/mme/MME_Tests.ttcn b/mme/MME_Tests.ttcn
index c006aa4..4885b1e 100644
--- a/mme/MME_Tests.ttcn
+++ b/mme/MME_Tests.ttcn
@@ -120,7 +120,7 @@

/* S11 interface (GTPv2C) of emulated SGW-C */
var GTPv2_Emulation_CT vc_GTP2;
- port GTP2EM_PT TEID0;
+ port GTP2EM_PT TEIC0;

var UeParams g_ue_pars[NUM_UE];
}
@@ -371,15 +371,12 @@
gtpc_bind_port := mp_s11_local_port,
gtpc_remote_ip := mp_s11_remote_ip,
gtpc_remote_port := mp_s11_remote_port,
- gtpu_bind_ip := omit, /* using gtpu daemon */
- gtpu_bind_port := omit, /* using gtpu daemon */
- sgw_role := true,
- use_gtpu_daemon := false
+ sgw_role := true
};

vc_GTP2 := GTPv2_Emulation_CT.create(id);
map(vc_GTP2:GTP2C, system:GTP2C);
- connect(vc_GTP2:TEID0, self:TEID0);
+ connect(vc_GTP2:TEIC0, self:TEIC0);
vc_GTP2.start(GTPv2_Emulation.main(cfg));
}

@@ -840,9 +837,9 @@
g_pars.ue_pars.bearer.ebi := rx_bctx_ies.ePS_Bearer_ID.ePS_Bearer_ID_Value;

/* allocate + register TEID-C on local side */
- g_pars.ue_pars.s11_teic_local := f_gtp2_allocate_teid();
+ g_pars.ue_pars.s11_teic_local := f_gtp2_allocate_teic();
g_pars.ue_pars.bearer.s11_teid_local := g_pars.ue_pars.s11_teic_local;
- g_pars.ue_pars.s5c_teic_local := f_gtp2_allocate_teid();
+ g_pars.ue_pars.s5c_teic_local := f_gtp2_allocate_teic();
g_pars.ue_pars.bearer.s5c_teid_local := g_pars.ue_pars.s5c_teic_local;

s11_fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S11_MME_GTPC, g_pars.ue_pars.s11_teic_local, 0,
diff --git a/mme/gen_links.sh b/mme/gen_links.sh
index af0355f..ea9179f 100755
--- a/mme/gen_links.sh
+++ b/mme/gen_links.sh
@@ -55,10 +55,6 @@
FILES="GTPv2_Types.ttcn"
gen_links $DIR $FILES

-DIR=$BASEDIR/osmo-uecups/ttcn3
-FILES="UECUPS_CodecPort.ttcn UECUPS_CodecPort_CtrlFunct.ttcn UECUPS_CodecPort_CtrlFunctDef.cc UECUPS_Types.ttcn "
-gen_links $DIR $FILES
-
DIR=$BASEDIR/titan.ProtocolModules.DIAMETER_ProtocolModule_Generator/src
FILES="DIAMETER_EncDec.cc"
gen_links $DIR $FILES
diff --git a/mme/regen_makefile.sh b/mme/regen_makefile.sh
index 4eb0f1a..c1859da 100755
--- a/mme/regen_makefile.sh
+++ b/mme/regen_makefile.sh
@@ -26,7 +26,6 @@
TCCEncoding.cc
TCCInterface.cc
TELNETasp_PT.cc
- UECUPS_CodecPort_CtrlFunctDef.cc
"

. ../_buildsystem/regen_makefile.inc.sh
diff --git a/pgw/PGW_Tests.cfg b/pgw/PGW_Tests.cfg
index ce3076b..68688c1 100644
--- a/pgw/PGW_Tests.cfg
+++ b/pgw/PGW_Tests.cfg
@@ -20,7 +20,7 @@
PGW_Tests.mp_pcrf_local_ip:= "127.0.0.202"
PGW_Tests.mp_ocs_local_ip:= "127.0.0.202"
PGW_Tests.mp_aaa_local_ip:= "127.0.0.202"
-GTPv2_Emulation.mp_uecups_host := "127.0.0.20"
+GTPv1U_Emulation.mp_uecups_host := "127.0.0.20"

[MAIN_CONTROLLER]

diff --git a/pgw/PGW_Tests.ttcn b/pgw/PGW_Tests.ttcn
index 4a4f77f..4d225fa 100644
--- a/pgw/PGW_Tests.ttcn
+++ b/pgw/PGW_Tests.ttcn
@@ -7,6 +7,8 @@
import from Native_Functions all;
import from Misc_Helpers all;

+import from GTPv1U_Emulation all;
+
import from GTPv2_Types all;
import from GTPv2_Templates all;
import from GTPv2_Emulation all;
@@ -47,9 +49,11 @@
}

/* main component, we typically have one per testcase */
-type component PGW_Test_CT extends GTP2_ConnHdlr {
+type component PGW_Test_CT extends GTP2_ConnHdlr, GTP1U_ConnHdlr {
var GTPv2_Emulation_CT vc_GTP2;
- port GTP2EM_PT TEID0;
+ port GTP2EM_PT TEIC0;
+ var GTPv1U_Emulation_CT vc_GTP1U;
+ port GTP1UEM_PT TEID0;

/* emulated PCRF */
var DIAMETER_Emulation_CT vc_Gx;
@@ -100,7 +104,7 @@


/* per-session component; we typically have 1..N per testcase */
-type component PGW_Session_CT extends GTP2_ConnHdlr {
+type component PGW_Session_CT extends GTP2_ConnHdlr, GTP1U_ConnHdlr {
var SessionPars g_pars;

port DIAMETER_Conn_PT Gx;
@@ -280,27 +284,44 @@
f_sleep(1.0);
}

-private function f_init(float guard_timeout := 60.0) runs on PGW_Test_CT {
- T_guard.start(guard_timeout);
- activate(as_Tguard());
-
+private function f_init_gtp2c() runs on PGW_Test_CT {
var Gtp2EmulationCfg cfg := {
gtpc_bind_ip := mp_local_hostname_c,
gtpc_bind_port := GTP2C_PORT,
gtpc_remote_ip := mp_pgw_hostname,
gtpc_remote_port := GTP2C_PORT,
- gtpu_bind_ip := omit, /* using gtpu daemon */
- gtpu_bind_port := omit, /* using gtpu daemon */
- sgw_role := true,
- use_gtpu_daemon := true
+ sgw_role := true
};

- vc_GTP2 := GTPv2_Emulation_CT.create("GTP2_EM");
+ vc_GTP2 := GTPv2_Emulation_CT.create("GTP2C_EM");
map(vc_GTP2:GTP2C, system:GTP2C);
- connect(vc_GTP2:TEID0, self:TEID0);
+ connect(vc_GTP2:TEIC0, self:TEIC0);
connect(vc_GTP2:CLIENT, self:GTP2);
connect(vc_GTP2:CLIENT_PROC, self:GTP2_PROC);
vc_GTP2.start(GTPv2_Emulation.main(cfg));
+}
+
+private function f_init_gtp1u() runs on PGW_Test_CT {
+ var Gtp1uEmulationCfg cfg := {
+ gtpu_bind_ip := omit, /* using gtpu daemon */
+ gtpu_bind_port := omit, /* using gtpu daemon */
+ use_gtpu_daemon := true
+ };
+
+ vc_GTP1U := GTPv1U_Emulation_CT.create("GTP1U_EM");
+ map(vc_GTP1U:GTP1U, system:GTP1U);
+ connect(vc_GTP1U:TEID0, self:TEID0);
+ connect(vc_GTP1U:CLIENT, self:GTP1U);
+ connect(vc_GTP1U:CLIENT_PROC, self:GTP1U_PROC);
+ vc_GTP1U.start(GTPv1U_Emulation.main(cfg));
+}
+
+private function f_init(float guard_timeout := 60.0) runs on PGW_Test_CT {
+ T_guard.start(guard_timeout);
+ activate(as_Tguard());
+
+ f_init_gtp2c();
+ f_init_gtp1u();

if (mp_pcrf_local_ip != "") {
f_init_diameter(testcasename());
@@ -323,6 +344,8 @@
vc_conn := PGW_Session_CT.create(id);
connect(vc_conn:GTP2, vc_GTP2:CLIENT);
connect(vc_conn:GTP2_PROC, vc_GTP2:CLIENT_PROC);
+ connect(vc_conn:GTP1U, vc_GTP1U:CLIENT);
+ connect(vc_conn:GTP1U_PROC, vc_GTP1U:CLIENT_PROC);

if (isbound(vc_Gx)) {
vc_conn_gx := DIAMETER_ConnHdlr_CT.create(id);
@@ -355,9 +378,9 @@
private function f_handler_init(void_fn fn, SessionPars pars)
runs on PGW_Session_CT {
g_pars := valueof(pars);
- /* allocate + register TEID-C on local side */
- g_pars.teic_local := f_gtp2_allocate_teid();
- g_pars.bearer.teid_local := g_pars.teic_local;
+ /* allocate + register TEI{C,D} on local side */
+ g_pars.teic_local := f_gtp2_allocate_teic();
+ g_pars.bearer.teid_local := f_gtp1u_allocate_teid();
fn.apply();
}

@@ -693,12 +716,12 @@
/* create tunnel in daemon */
if (isbound(g_ip4_addr)) {
uecups_create.user_addr := g_ip4_addr;
- f_gtp2_create_tunnel(uecups_create);
+ f_gtp1u_create_tunnel(uecups_create);
}
if (isbound(g_ip6_addr)) {
uecups_create.user_addr_type := IPV6;
uecups_create.user_addr := g_ip6_addr;
- f_gtp2_create_tunnel(uecups_create);
+ f_gtp1u_create_tunnel(uecups_create);
}
}

@@ -871,7 +894,7 @@
rx_teid := oct2int(g_pars.bearer.teid_local)
};
/* FIXME: what about IPv4/IPv6 differentiation? */
- f_gtp2_destroy_tunnel(uecups_destroy);
+ f_gtp1u_destroy_tunnel(uecups_destroy);
}
}

@@ -896,7 +919,7 @@
}

log("Starting a program: ", command);
- var UECUPS_StartProgramRes res := f_gtp2_start_program(sprog);
+ var UECUPS_StartProgramRes res := f_gtp1u_start_program(sprog);
if (res.result != OK) {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
log2str("Unable to start program '", command, "'"));
@@ -914,10 +937,10 @@

T.start;
alt {
- [] GTP2.receive(UECUPS_ProgramTermInd:{pid := pid, exit_code := exit_code}) {
+ [] GTP1U.receive(UECUPS_ProgramTermInd:{pid := pid, exit_code := exit_code}) {
setverdict(pass);
}
- [] GTP2.receive(UECUPS_ProgramTermInd:?) -> value pti {
+ [] GTP1U.receive(UECUPS_ProgramTermInd:?) -> value pti {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
log2str("Received unexpected ProgramTermInd := ", pti));
}
diff --git a/pgw/gen_links.sh b/pgw/gen_links.sh
index 314050e..fa69ee4 100755
--- a/pgw/gen_links.sh
+++ b/pgw/gen_links.sh
@@ -59,7 +59,8 @@

DIR=../library
FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPCP_Types.ttcn IPCP_Templates.ttcn PAP_Types.ttcn "
-FILES+="GTPv1C_CodecPort.ttcn GTPv1C_CodecPort_CtrlFunct.ttcn GTPv1C_CodecPort_CtrlFunctDef.cc GTPv1U_CodecPort.ttcn GTPv1U_CodecPort_CtrlFunct.ttcn GTPv1U_CodecPort_CtrlFunctDef.cc GTPv1C_Templates.ttcn Osmocom_Gb_Types.ttcn "
+FILES+="GTPv1C_CodecPort.ttcn GTPv1C_CodecPort_CtrlFunct.ttcn GTPv1C_CodecPort_CtrlFunctDef.cc GTPv1C_Templates.ttcn Osmocom_Gb_Types.ttcn "
+FILES+="GTPv1U_CodecPort.ttcn GTPv1U_CodecPort_CtrlFunct.ttcn GTPv1U_CodecPort_CtrlFunctDef.cc GTPv1U_Emulation.ttcn "
FILES+="GTPv2_PrivateExtensions.ttcn GTPv2_Templates.ttcn "
FILES+="GTPv2_CodecPort.ttcn GTPv2_CodecPort_CtrlFunctDef.cc GTPv2_CodecPort_CtrlFunct.ttcn GTPv2_Emulation.ttcn "
FILES+="DNS_Helpers.ttcn "

To view, visit change 40744. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: Ia45307107753294c6761cb588f0ab769821eb213
Gerrit-Change-Number: 40744
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>