GTPv2_Emulation: Add support to handle GTPv1-U

Change-Id: I34c744015c09a387cbf736063303bdb61ca4744e
diff --git a/epdg/EPDG_Tests.ttcn b/epdg/EPDG_Tests.ttcn
index 6263828..92f49ff 100644
--- a/epdg/EPDG_Tests.ttcn
+++ b/epdg/EPDG_Tests.ttcn
@@ -18,6 +18,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_Templates all;
+
 import from GTPv2_Types all;
 import from GTPv2_Templates all;
 import from GTPv2_Emulation all;
@@ -50,6 +54,8 @@
 	charstring mp_s2b_dns_ipv6 := "::1";
 	charstring mp_s2b_pcscf_ipv4 := "5.6.7.8";
 	charstring mp_s2b_pcscf_ipv6 := "::2";
+	/* our emulated PGW /* GTP1U */
+	charstring mp_upf_gtpu_local_ip := "127.0.0.100";
 
 	charstring mp_diam_realm := "localdomain";
 	integer mp_diam_watchdog_initial_wait_sec := 6*3;
@@ -289,6 +295,8 @@
 		gtpc_bind_port := mp_s2b_local_port,
 		gtpc_remote_ip := mp_s2b_remote_ip,
 		gtpc_remote_port := mp_s2b_remote_port,
+		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 */
 	};
diff --git a/epdg/gen_links.sh b/epdg/gen_links.sh
index f981586..ed4209c 100755
--- a/epdg/gen_links.sh
+++ b/epdg/gen_links.sh
@@ -33,6 +33,10 @@
 FILES="UECUPS_CodecPort.ttcn  UECUPS_CodecPort_CtrlFunct.ttcn  UECUPS_CodecPort_CtrlFunctDef.cc UECUPS_Types.ttcn "
 gen_links $DIR $FILES
 
+DIR=$BASEDIR/titan.ProtocolModules.GTP_v13.5.0/src
+FILES="GTPU_EncDec.cc GTPU_Types.ttcn "
+gen_links $DIR $FILES
+
 DIR=$BASEDIR/titan.ProtocolModules.GTPv2_v13.7.0/src
 FILES="GTPv2_Types.ttcn"
 gen_links $DIR $FILES
@@ -47,6 +51,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+="GTPv2_PrivateExtensions.ttcn GTPv2_Templates.ttcn "
 FILES+="GTPv2_CodecPort.ttcn GTPv2_CodecPort_CtrlFunctDef.cc GTPv2_CodecPort_CtrlFunct.ttcn GTPv2_Emulation.ttcn "
 gen_links $DIR $FILES
diff --git a/epdg/regen_makefile.sh b/epdg/regen_makefile.sh
index 8be3bde..eb5935e 100755
--- a/epdg/regen_makefile.sh
+++ b/epdg/regen_makefile.sh
@@ -16,6 +16,8 @@
 	DIAMETER_EncDec.cc
 	DIAMETER_CodecPort_CtrlFunctDef.cc
 	UECUPS_CodecPort_CtrlFunctDef.cc
+	GTPU_EncDec.cc
+	GTPv1U_CodecPort_CtrlFunctDef.cc
 	GTPv2_CodecPort_CtrlFunctDef.cc
 "
 
diff --git a/library/GTPv2_Emulation.ttcn b/library/GTPv2_Emulation.ttcn
index 054bd4b..f3f09f8 100644
--- a/library/GTPv2_Emulation.ttcn
+++ b/library/GTPv2_Emulation.ttcn
@@ -14,6 +14,9 @@
 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;
@@ -40,8 +43,8 @@
 	IPL4asp_Types.PortNumber gtpc_bind_port,
 	HostName gtpc_remote_ip,
 	IPL4asp_Types.PortNumber gtpc_remote_port,
-	//HostName gtpu_bind_ip,
-	//PortNumber gtpu_bind_port,
+	HostName gtpu_bind_ip optional,
+	IPL4asp_Types.PortNumber gtpu_bind_port optional,
 	boolean sgw_role,
 	boolean use_gtpu_daemon
 };
@@ -49,6 +52,7 @@
 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;
@@ -63,7 +67,7 @@
 
 	/* State */
 	var Gtp2cPeer g_peer;
-	var integer g_gtp2c_id;
+	var integer g_gtp2c_id, g_gtp1u_id;
 	var OCT1 g_restart_ctr;
 	var uint16_t g_c_seq_nr;
 	var TidTableRec TidTable[256];
@@ -508,6 +512,11 @@
 
 		/* 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 */
@@ -543,6 +552,7 @@
 
 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;
@@ -589,6 +599,16 @@
 		}
 
 		}
+	[] 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 {
 		/* patch in the next sequence number on outbound Initial message */
@@ -603,6 +623,9 @@
 			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 */
@@ -617,6 +640,9 @@
 			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);
@@ -662,7 +688,7 @@
  * Interaction between Main and Client Components
  ***********************************************************************/
 type port GTP2EM_PT message {
-	inout PDU_GTPCv2, UECUPS_ProgramTermInd;
+	inout PDU_GTPCv2, Gtp1uUnitdata, UECUPS_ProgramTermInd;
 } with { extension "internal" };
 
 signature GTP2EM_register_imsi(hexstring imsi);