Split GTP_CodecPort/GTP_Templates into C and U variants

The Types are already split in the dependent modules in GTPC_Types and
GTPU_Types.
There's no point in keeping them together in the same file since those 2
protocols are mostly independent.
Furthermore, testsuites using GTPv2C + GTPv1U don't need GTPv1C.

Change-Id: Ic15c9a2e92828cbafb4dda7355ee534107051e2d
diff --git a/library/GTP_Emulation.ttcn b/library/GTP_Emulation.ttcn
index 689fb0d..f5c0eef 100644
--- a/library/GTP_Emulation.ttcn
+++ b/library/GTP_Emulation.ttcn
@@ -16,8 +16,10 @@
 import from Osmocom_Types all;
 import from GTPC_Types all;
 import from GTPU_Types all;
-import from GTP_CodecPort all;
-import from GTP_CodecPort_CtrlFunct all;
+import from GTPv1C_CodecPort all;
+import from GTPv1U_CodecPort all;
+import from GTPv1C_CodecPort_CtrlFunct all;
+import from GTPv1U_CodecPort_CtrlFunct all;
 
 /***********************************************************************
  * Main Emulation Component
@@ -172,13 +174,13 @@
 	var Result res;
 
 	map(self:GTPC, system:GTPC);
-	res := GTP_CodecPort_CtrlFunct.f_IPL4_listen(GTPC, cfg.gtpc_bind_ip,
+	res := GTPv1C_CodecPort_CtrlFunct.f_IPL4_listen(GTPC, cfg.gtpc_bind_ip,
 						     cfg.gtpc_bind_port, {udp:={}});
 	g_gtpc_id := res.connId;
 
 	if (isvalue(cfg.gtpu_bind_ip) and isvalue(cfg.gtpu_bind_port)) {
 		map(self:GTPU, system:GTPU);
-		res := GTP_CodecPort_CtrlFunct.f_GTPU_listen(GTPU, cfg.gtpu_bind_ip,
+		res := GTPv1U_CodecPort_CtrlFunct.f_GTPU_listen(GTPU, cfg.gtpu_bind_ip,
 							     cfg.gtpu_bind_port, {udp:={}});
 		g_gtpu_id := res.connId;
 	}
diff --git a/library/GTP_CodecPort.ttcn b/library/GTPv1C_CodecPort.ttcn
similarity index 61%
rename from library/GTP_CodecPort.ttcn
rename to library/GTPv1C_CodecPort.ttcn
index b516611..956a674 100644
--- a/library/GTP_CodecPort.ttcn
+++ b/library/GTPv1C_CodecPort.ttcn
@@ -1,4 +1,4 @@
-/* dual-faced port sitting on top of IPL4_asp UDP to encode/decode GTP
+/* dual-faced port sitting on top of IPL4_asp UDP to encode/decode GTPv1C
  * (C) 2017 Harald Welte <laforge@gnumonks.org>
  * All rights reserved.
  *
@@ -9,11 +9,10 @@
  */
 
 
-module GTP_CodecPort {
+module GTPv1C_CodecPort {
 	import from IPL4asp_PortType all;
 	import from IPL4asp_Types all;
 	import from GTPC_Types all;
-	import from GTPU_Types all;
 	import from Misc_Helpers all;
 
 	modulepar {
@@ -21,7 +20,7 @@
 	}
 
 	/* identifies a remote peer (sender or receiver) */
-	type record GtpPeer {
+	type record Gtp1cPeer {
 		ConnectionId	connId,
 		HostName	remName,
 		PortNumber	remPort
@@ -29,16 +28,10 @@
 
 	/* Decoded GTP1C (Control Plane), used in send and receive direction */
 	type record Gtp1cUnitdata {
-		GtpPeer		peer,
+		Gtp1cPeer		peer,
 		PDU_GTPC	gtpc
 	}
 
-	/* Decoded GTP1U (User Plane), used in send and receive direction */
-	type record Gtp1uUnitdata {
-		GtpPeer		peer,
-		PDU_GTPU	gtpu
-	}
-
  	/* Translation port on top of IPL4asp; ASP_Event passed through transparently */
 	type port GTPC_PT message {
 		out	Gtp1cUnitdata;
@@ -69,33 +62,4 @@
 				log2str("Rx GTPv1-C with field length ", out_ud.gtpc.lengthf, " + 8 != exp ", lengthof(in_ud.msg)));
 		}
 	} with { extension "prototype(fast)" };
-
-
-	/* dual-faced port on top of IPL4asp; ASP_Event passed through transparently */
-	type port GTPU_PT message {
-		out	Gtp1uUnitdata;
-		in	Gtp1uUnitdata,
-			ASP_ConnId_ReadyToRelease,
-			ASP_Event;
-	} with { extension "user IPL4asp_PT
-		out(Gtp1uUnitdata -> ASP_SendTo: function(f_enc_Gtp1uUD))
-		in(ASP_RecvFrom -> Gtp1uUnitdata: function(f_dec_Gtp1uUD);
-		   ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple;
-		   ASP_Event -> ASP_Event: simple)" }
-
-	function f_enc_Gtp1uUD(in Gtp1uUnitdata in_ud, out ASP_SendTo out_ud) {
-		out_ud.connId := in_ud.peer.connId;
-		out_ud.remName := in_ud.peer.remName;
-		out_ud.remPort := in_ud.peer.remPort;
-		out_ud.proto := { udp := {} };
-		out_ud.msg := enc_PDU_GTPU(in_ud.gtpu);
-	} with { extension "prototype(fast)" };
-
-	function f_dec_Gtp1uUD(in ASP_RecvFrom in_ud, out Gtp1uUnitdata out_ud) {
-		out_ud.peer.connId := in_ud.connId;
-		out_ud.peer.remName := in_ud.remName;
-		out_ud.peer.remPort := in_ud.remPort;
-		out_ud.gtpu := dec_PDU_GTPU(in_ud.msg);
-	} with { extension "prototype(fast)" };
-
 }
diff --git a/library/GTP_CodecPort_CtrlFunct.ttcn b/library/GTPv1C_CodecPort_CtrlFunct.ttcn
similarity index 78%
rename from library/GTP_CodecPort_CtrlFunct.ttcn
rename to library/GTPv1C_CodecPort_CtrlFunct.ttcn
index 4f61af7..e0a5ee7 100644
--- a/library/GTP_CodecPort_CtrlFunct.ttcn
+++ b/library/GTPv1C_CodecPort_CtrlFunct.ttcn
@@ -1,6 +1,6 @@
-module GTP_CodecPort_CtrlFunct {
+module GTPv1C_CodecPort_CtrlFunct {
 
-  import from GTP_CodecPort all;
+  import from GTPv1C_CodecPort all;
   import from IPL4asp_Types all;
 
   external function f_IPL4_listen(
@@ -39,12 +39,4 @@
     in ConnectionId id,
     out UserData userData
   ) return Result;
-
-  external function f_GTPU_listen(
-    inout GTPU_PT portRef,
-    in HostName locName,
-    in PortNumber locPort,
-    in ProtoTuple proto,
-    in OptionList options := {}
-  ) return Result;
 }
diff --git a/library/GTP_CodecPort_CtrlFunctDef.cc b/library/GTPv1C_CodecPort_CtrlFunctDef.cc
similarity index 69%
rename from library/GTP_CodecPort_CtrlFunctDef.cc
rename to library/GTPv1C_CodecPort_CtrlFunctDef.cc
index c0b9391..2227fe1 100644
--- a/library/GTP_CodecPort_CtrlFunctDef.cc
+++ b/library/GTPv1C_CodecPort_CtrlFunctDef.cc
@@ -1,11 +1,11 @@
 #include "IPL4asp_PortType.hh"
 #include "IPL4asp_PT.hh"
-#include "GTP_CodecPort.hh"
+#include "GTPv1C_CodecPort.hh"
 
-namespace GTP__CodecPort__CtrlFunct {
+namespace GTPv1C__CodecPort__CtrlFunct {
 
   IPL4asp__Types::Result f__IPL4__listen(
-    GTP__CodecPort::GTPC__PT& portRef,
+    GTPv1C__CodecPort::GTPC__PT& portRef,
     const IPL4asp__Types::HostName& locName,
     const IPL4asp__Types::PortNumber& locPort,
     const IPL4asp__Types::ProtoTuple& proto,
@@ -13,9 +13,9 @@
   {
     return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options);
   }
-  
+
   IPL4asp__Types::Result f__IPL4__connect(
-    GTP__CodecPort::GTPC__PT& portRef,
+    GTPv1C__CodecPort::GTPC__PT& portRef,
     const IPL4asp__Types::HostName& remName,
     const IPL4asp__Types::PortNumber& remPort,
     const IPL4asp__Types::HostName& locName,
@@ -29,38 +29,27 @@
   }
 
   IPL4asp__Types::Result f__IPL4__close(
-    GTP__CodecPort::GTPC__PT& portRef, 
-    const IPL4asp__Types::ConnectionId& connId, 
+    GTPv1C__CodecPort::GTPC__PT& portRef,
+    const IPL4asp__Types::ConnectionId& connId,
     const IPL4asp__Types::ProtoTuple& proto)
   {
       return f__IPL4__PROVIDER__close(portRef, connId, proto);
   }
 
   IPL4asp__Types::Result f__IPL4__setUserData(
-    GTP__CodecPort::GTPC__PT& portRef,
+    GTPv1C__CodecPort::GTPC__PT& portRef,
     const IPL4asp__Types::ConnectionId& connId,
     const IPL4asp__Types::UserData& userData)
   {
     return f__IPL4__PROVIDER__setUserData(portRef, connId, userData);
   }
-  
+
   IPL4asp__Types::Result f__IPL4__getUserData(
-    GTP__CodecPort::GTPC__PT& portRef,
+    GTPv1C__CodecPort::GTPC__PT& portRef,
     const IPL4asp__Types::ConnectionId& connId,
     IPL4asp__Types::UserData& userData)
   {
     return f__IPL4__PROVIDER__getUserData(portRef, connId, userData);
   }
 
-
-  IPL4asp__Types::Result f__GTPU__listen(
-    GTP__CodecPort::GTPU__PT& portRef,
-    const IPL4asp__Types::HostName& locName,
-    const IPL4asp__Types::PortNumber& locPort,
-    const IPL4asp__Types::ProtoTuple& proto,
-    const IPL4asp__Types::OptionList& options)
-  {
-    return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options);
-  }
-
 }
diff --git a/library/GTP_Templates.ttcn b/library/GTPv1C_Templates.ttcn
similarity index 90%
rename from library/GTP_Templates.ttcn
rename to library/GTPv1C_Templates.ttcn
index 30346d4..4a0c8b2 100644
--- a/library/GTP_Templates.ttcn
+++ b/library/GTPv1C_Templates.ttcn
@@ -1,4 +1,4 @@
-/* GTP Templates in TTCN-3
+/* GTPv1-C Templates in TTCN-3
  * (C) 2018 Harald Welte <laforge@gnumonks.org>
  * contributions by sysmocom - s.f.m.c. GmbH
  * All rights reserved.
@@ -9,13 +9,12 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-module GTP_Templates {
+module GTPv1C_Templates {
 
 	import from General_Types all;
 	import from Osmocom_Types all;
 	import from GTPC_Types all;
-	import from GTPU_Types all;
-	import from GTP_CodecPort all;
+	import from GTPv1C_CodecPort all;
 	import from IPCP_Types all;
 	import from GSM_Types all; // RoutingAreaIdentification, CellIdentity
 
@@ -416,7 +415,7 @@
 
 
 	/* template matching reception of GTP-C unit-data */
-	template (present) Gtp1cUnitdata tr_GTPC_MsgType(template (present) GtpPeer peer,
+	template (present) Gtp1cUnitdata tr_GTPC_MsgType(template (present) Gtp1cPeer peer,
 							 template (present) OCT1 msg_type,
 							 template (present) OCT4 teid,
 							 template (present) GTPC_PDUs pdus := ?) := {
@@ -425,7 +424,7 @@
 	}
 
 	/* template matching reception of GTP-C echo-request */
-	template (present) Gtp1cUnitdata tr_GTPC_PING(template (present) GtpPeer peer) := tr_GTPC_MsgType(peer, echoRequest, '00000000'O);
+	template (present) Gtp1cUnitdata tr_GTPC_PING(template (present) Gtp1cPeer peer) := tr_GTPC_MsgType(peer, echoRequest, '00000000'O);
 
 	template (present) GTPC_PDUs tr_EchoRespPDU(template (present) OCT1 restart_counter) := {
 		echoResponse := {
@@ -435,7 +434,7 @@
 	}
 
 	/* template matching reception of GTP-C echo-response */
-	template (present) Gtp1cUnitdata tr_GTPC_PONG(template (present) GtpPeer peer) := tr_GTPC_MsgType(peer, echoResponse, '00000000'O, tr_EchoRespPDU(?));
+	template (present) Gtp1cUnitdata tr_GTPC_PONG(template (present) Gtp1cPeer peer) := tr_GTPC_MsgType(peer, echoResponse, '00000000'O, tr_EchoRespPDU(?));
 
 	template (value) GTPC_PDUs ts_EchoRespPDU(OCT1 restart_counter) := {
 		echoResponse := {
@@ -445,7 +444,7 @@
 	}
 
 	/* master template for senidng a GTP-C echo response */
-	template (value) Gtp1cUnitdata ts_GTPC_PONG(GtpPeer peer, uint16_t seq, OCT1 rest_ctr) := {
+	template (value) Gtp1cUnitdata ts_GTPC_PONG(Gtp1cPeer peer, uint16_t seq, OCT1 rest_ctr) := {
 		peer := peer,
 		gtpc := ts_GTP1C_PDU(echoResponse, '00000000'O, valueof(ts_EchoRespPDU(rest_ctr)), seq)
 	}
@@ -457,7 +456,7 @@
 	}
 
 	/* master template for sending a GTP-C echo request */
-	template (value) Gtp1cUnitdata ts_GTPC_PING(GtpPeer peer, uint16_t seq) := {
+	template (value) Gtp1cUnitdata ts_GTPC_PING(Gtp1cPeer peer, uint16_t seq) := {
 		peer := peer,
 		gtpc := ts_GTP1C_PDU(echoRequest, '00000000'O, valueof(ts_EchoReqPDU), seq)
 	}
@@ -787,7 +786,7 @@
 		}
 	}
 
-	template (value) Gtp1cUnitdata ts_GTPC_CreatePDP(GtpPeer peer, uint16_t seq, hexstring imsi,
+	template (value) Gtp1cUnitdata ts_GTPC_CreatePDP(Gtp1cPeer peer, uint16_t seq, hexstring imsi,
 							 OCT1 restart_ctr, OCT4 teid_data,
 							 OCT4 teid_ctrl, BIT4 nsapi, EndUserAddress eua,
 							 octetstring apn, octetstring sgsn_ip_sign,
@@ -859,7 +858,7 @@
 		}
 	}
 
-	template (value) Gtp1cUnitdata ts_GTPC_UpdatePDP(GtpPeer peer, OCT4 teid, uint16_t seq, hexstring imsi,
+	template (value) Gtp1cUnitdata ts_GTPC_UpdatePDP(Gtp1cPeer peer, OCT4 teid, uint16_t seq, hexstring imsi,
 							 OCT1 restart_ctr, OCT4 teid_data,
 							 OCT4 teid_ctrl, BIT4 nsapi, octetstring sgsn_ip_sign,
 							 octetstring sgsn_ip_data,
@@ -928,7 +927,7 @@
 		}
 	}
 
-	template (value) Gtp1cUnitdata ts_GTPC_CreatePdpResp(GtpPeer peer, uint16_t seq, OCT4 teid,
+	template (value) Gtp1cUnitdata ts_GTPC_CreatePdpResp(Gtp1cPeer peer, uint16_t seq, OCT4 teid,
 							     OCT1 cause,
 							     OCT4 teid_ctrl, OCT4 teid_data,
 							     BIT4 nsapi, octetstring ggsn_ip_sign,
@@ -1132,7 +1131,7 @@
 		}
 	}
 
-	template (value) Gtp1cUnitdata ts_GTPC_DeletePDP(GtpPeer peer, uint16_t seq, OCT4 teid,
+	template (value) Gtp1cUnitdata ts_GTPC_DeletePDP(Gtp1cPeer peer, uint16_t seq, OCT4 teid,
 							 BIT4 nsapi, template (omit) BIT1 teardown_ind) := {
 		peer := peer,
 		gtpc := ts_GTP1C_PDU(deletePDPContextRequest, teid,
@@ -1151,7 +1150,7 @@
 		}
 	}
 
-	template (value) Gtp1cUnitdata ts_GTPC_DeletePdpResp(GtpPeer peer, uint16_t seq, OCT4 teid,
+	template (value) Gtp1cUnitdata ts_GTPC_DeletePdpResp(Gtp1cPeer peer, uint16_t seq, OCT4 teid,
 							     OCT1 cause,
 							     template (omit) ProtConfigOptions pco := omit) := {
 		peer := peer,
@@ -1188,7 +1187,7 @@
 			private_extension_gtpc := *
 		}
 	}
-	template (present) Gtp1cUnitdata tr_GTPC_SGSNContextReq(template (present) GtpPeer peer,
+	template (present) Gtp1cUnitdata tr_GTPC_SGSNContextReq(template (present) Gtp1cPeer peer,
 								template (present) GTPC_PDUs SGSNContextReqPDU) := {
 		peer := peer,
 		gtpc := tr_GTP1C_PDU(sgsnContextRequest, '00000000'O, SGSNContextReqPDU)
@@ -1221,7 +1220,7 @@
 			private_extension_gtpc := omit
 		}
 	}
-	template (value) Gtp1cUnitdata ts_GTPC_SGSNContextReq(GtpPeer peer, uint16_t seq,
+	template (value) Gtp1cUnitdata ts_GTPC_SGSNContextReq(Gtp1cPeer peer, uint16_t seq,
 							      template (value) GTPC_PDUs SGSNContextReqPDU) := {
 		peer := peer,
 		gtpc := ts_GTP1C_PDU(sgsnContextRequest, '00000000'O, valueof(SGSNContextReqPDU), seq)
@@ -1262,7 +1261,7 @@
 			private_extension_gtpc := *
 		}
 	}
-	template (present) Gtp1cUnitdata tr_GTPC_SGSNContextResp(template (present) GtpPeer peer := ?,
+	template (present) Gtp1cUnitdata tr_GTPC_SGSNContextResp(template (present) Gtp1cPeer peer := ?,
 								 template (present) OCT4 teid := ?,
 								 template (present) GTPC_PDUs SGSNContextRespPDU := ?)
 		:= tr_GTPC_MsgType(peer, sgsnContextResponse, teid, SGSNContextRespPDU);
@@ -1305,7 +1304,7 @@
 			private_extension_gtpc := omit
 		}
 	}
-	template (value) Gtp1cUnitdata ts_GTPC_SGSNContextResp(GtpPeer peer, OCT4 teid, uint16_t seq,
+	template (value) Gtp1cUnitdata ts_GTPC_SGSNContextResp(Gtp1cPeer peer, OCT4 teid, uint16_t seq,
 							      template (value) GTPC_PDUs SGSNContextRespPDU) := {
 		peer := peer,
 		gtpc := ts_GTP1C_PDU(sgsnContextResponse, teid, valueof(SGSNContextRespPDU), seq)
@@ -1323,7 +1322,7 @@
 			private_extension_gtpc := *
 		}
 	}
-	template (present) Gtp1cUnitdata tr_GTPC_SGSNContextAck(template (present) GtpPeer peer := ?,
+	template (present) Gtp1cUnitdata tr_GTPC_SGSNContextAck(template (present) Gtp1cPeer peer := ?,
 								 template (present) OCT4 teid := ?,
 								 template (present) GTPC_PDUs SGSNContextAckPDU := ?)
 		:= tr_GTPC_MsgType(peer, sgsnContextAcknowledge, teid, SGSNContextAckPDU);
@@ -1337,7 +1336,7 @@
 			private_extension_gtpc := omit
 		}
 	}
-	template (value) Gtp1cUnitdata ts_GTPC_SGSNContextAck(GtpPeer peer, OCT4 teid, uint16_t seq,
+	template (value) Gtp1cUnitdata ts_GTPC_SGSNContextAck(Gtp1cPeer peer, OCT4 teid, uint16_t seq,
 							      template (value) GTPC_PDUs SGSNContextAckPDU := ts_SGSNContextAckPDU(GTP_CAUSE_REQUEST_ACCEPTED)) := {
 		peer := peer,
 		gtpc := ts_GTP1C_PDU(sgsnContextAcknowledge, teid, valueof(SGSNContextAckPDU), seq)
@@ -1730,13 +1729,13 @@
 		}
 	}
 	template (present) Gtp1cUnitdata
-	tr_GTPC_RANInfoRelay(template (present) GtpPeer peer,
+	tr_GTPC_RANInfoRelay(template (present) Gtp1cPeer peer,
 			     template (present) RANTransparentContainer transparentContainer) := {
 		peer := peer,
 		gtpc := tr_GTP1C_PDU(rANInformationRelay, '00000000'O, tr_RANInfoRelay(transparentContainer))
 	}
 	template (value) Gtp1cUnitdata
-	ts_GTPC_RANInfoRelay(template (value) GtpPeer peer,
+	ts_GTPC_RANInfoRelay(template (value) Gtp1cPeer peer,
 			     template (value) RANTransparentContainer transparentContainer,
 			     template (omit) RIM_RoutingAddress ra := omit,
 			     template (omit) RIM_RoutingAddress_Discriminator ra_discr := omit) := {
@@ -1765,157 +1764,6 @@
 		 sON_TransferApplicationIdentity := son_app_id
 	}
 
-	/* GTP-U */
-
-	template (present) PDU_GTPU tr_GTP1U_PDU(template (present) OCT1 msg_type,
-						 template (present) OCT4 teid,
-						 template (present) GTPU_IEs ies := ?) := {
-		pn_bit := ?,
-		s_bit := ?,
-		e_bit := ?,
-		spare := ?,
-		/* Protocol Type flag (PT) shall be set to '1' in GTP */
-		pt := '1'B,
-		/* Version shall be set to decimal 1 ('001'). */
-		version := '001'B,
-		messageType := msg_type,
-		lengthf := ?,
-		teid := teid,
-		opt_part := *,
-		gtpu_IEs := ies
-	}
-
-	function f_GTPU_s_bit(template (omit) uint16_t seq) return BIT1 {
-		if (istemplatekind(seq, "omit")) {
-			return '0'B;
-		}
-		return '1'B;
-	}
-
-	function f_GTPU_opt_part(template (omit) uint16_t seq) return template (omit) GTPU_Header_optional_part {
-		if (istemplatekind(seq, "omit")) {
-			return omit;
-		}
-		var GTPU_Header_optional_part ret := {
-			sequenceNumber := int2oct(valueof(seq), 2),
-			npduNumber := '00'O,
-			nextExtHeader := '00'O,
-			gTPU_extensionHeader_List := omit
-		};
-		return ret;
-	}
-
-	/* generalized GTP-U send template */
-	template (value) PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, template (omit) uint16_t seq, OCT4 teid, GTPU_IEs ies) := {
-		/* N-PDU Number flag (PN): the GTP-U header contains a meaningful N-PDU Number field if the PN
-		 * flag is set to 1. */
-		pn_bit := '0'B,	/* we assume the encoder overwrites this if an optional part is given */
-		/* If the Sequence Number flag (S) is set to '1' the sequence number field is present and
-		 * meaningful otherwise it is set to '0'. For GTP-U messages Echo Request, Echo Response,
-		 * Error Indication and Supported Extension Headers Notification, the S flag shall be set to '1'.
-		 *
-		 * Note that the caller must ensure that these conditions hold.
-		 * The caller can either pass a sequence number (we set s_bit to '1'B) when appropriate,
-		 * or may omit the sequence number (we set s_bit to '0'B). */
-		s_bit := f_GTPU_s_bit(seq),
-		/* Extension header presence */
-		e_bit := '0'B,
-		spare := '0'B,
-		/* Protocol Type flag (PT) shall be set to '1' in GTP */
-		pt := '1'B,
-		/* Version shall be set to decimal 1 ('001'). */
-		version := '001'B,
-		messageType := msg_type,
-		lengthf := 0,	/* we assume encoder overwrites this */
-		teid := teid,
-		opt_part := f_GTPU_opt_part(seq),
-		gtpu_IEs := ies
-	}
-
-	template (present) Gtp1uUnitdata tr_GTPU_MsgType(template (present) GtpPeer peer,
-							 template (present) OCT1 msg_type,
-							 template (present) OCT4 teid) := {
-		peer := peer,
-		gtpu := tr_GTP1U_PDU(msg_type, teid)
-	}
-
-
-	/* template matching reception of GTP-U echo-request/response */
-	template (present) Gtp1uUnitdata tr_GTPU_PING(template (present) GtpPeer peer) := tr_GTPU_MsgType(peer, echoRequest, '00000000'O);
-	template (present) Gtp1uUnitdata tr_GTPU_PONG(template (present) GtpPeer peer) := tr_GTPU_MsgType(peer, echoResponse, '00000000'O);
-
-	/* template matching reception of GTP-U GPDU */
-	template GTPU_IEs t_GPDU(template (present) octetstring data) := {
-		g_PDU_IEs := {
-			data := data
-		}
-	}
-	template (present) Gtp1uUnitdata tr_GTPU_GPDU(template (present) GtpPeer peer,
-						      template (present) OCT4 teid,
-						      template (present) octetstring data := ?) := {
-		peer := peer,
-		gtpu := tr_GTP1U_PDU('FF'O, teid, t_GPDU(data))
-	}
-
-	template (present) GTPU_IEs ts_UEchoReqPDU := {
-		echoRequest_IEs := {
-			private_extension_gtpu := omit
-		}
-	}
-
-	/* master template for sending a GTP-C echo request */
-	template (value) Gtp1uUnitdata ts_GTPU_PING(GtpPeer peer, uint16_t seq) := {
-		peer := peer,
-		gtpu := ts_GTP1U_PDU(echoRequest, seq, '00000000'O, valueof(ts_UEchoReqPDU))
-	}
-
-	template GTPU_IEs ts_UEchoRespPDU(OCT1 restart_counter) := {
-		echoResponse_IEs := {
-			recovery_gtpu := {
-				type_gtpu := '00'O, /* we assume encoder fixes? */
-				restartCounter := restart_counter
-			},
-			private_extension_gtpu := omit
-		}
-	}
-
-	/* master template for sending a GTP-U echo response */
-	template (present) Gtp1uUnitdata ts_GTPU_PONG(GtpPeer peer, uint16_t seq, OCT1 rest_ctr) := {
-		peer := peer,
-		gtpu := ts_GTP1U_PDU(echoResponse, seq, '00000000'O, valueof(ts_UEchoRespPDU(rest_ctr)))
-	}
-
-	template (value) GSNAddress_gtpu ts_UGsnAddr(octetstring ip_addr) := {
-		type_gtpu := '85'O,
-		lengthf := lengthof(ip_addr),
-		gSNAddressValue := ip_addr
-	}
-
-	template (value) TeidDataI_gtpu ts_UteidDataI(OCT4 teid) := {
-		type_gtpu := '10'O,
-		teidDataI := teid
-	}
-
-	template (value)  GTPU_IEs ts_UErrorIndication(OCT4 teid, octetstring gsn_addr) := {
-		errorIndication_IEs := {
-			teidDataI_gtpu := ts_UteidDataI(teid),
-			gSNAddress_gtpu := ts_UGsnAddr(gsn_addr),
-			private_extension_gtpu := omit
-		}
-	}
-
-	/* master template for sending a GTP-U Error indication */
-	template (value) Gtp1uUnitdata ts_GTPU_ErrorIndication(GtpPeer peer, uint16_t seq, OCT4 teid, octetstring gsn_addr) := {
-		peer := peer,
-		gtpu := ts_GTP1U_PDU('1A'O, seq, '00000000'O, valueof(ts_UErrorIndication(teid, gsn_addr)))
-	}
-
-	/* master template for sending a GTP-U user plane data */
-	template (value) Gtp1uUnitdata ts_GTP1U_GPDU(GtpPeer peer, template (omit) uint16_t seq, OCT4 teid, octetstring data) := {
-		peer := peer,
-		gtpu := ts_GTP1U_PDU('FF'O, seq, teid, { g_PDU_IEs := { data := data }})
-	}
-
 	/* 3GPP TS 29.060, section 7.7.57 */
 	template (value) RIM_RoutingAddress ts_RIM_RoutingAddress(octetstring addr_value) := {
 		type_gtpc := '9F'O,
diff --git a/library/GTPv1U_CodecPort.ttcn b/library/GTPv1U_CodecPort.ttcn
new file mode 100644
index 0000000..59c5ef3
--- /dev/null
+++ b/library/GTPv1U_CodecPort.ttcn
@@ -0,0 +1,58 @@
+/* dual-faced port sitting on top of IPL4_asp UDP to encode/decode GTPv1-U
+ * (C) 2017 Harald Welte <laforge@gnumonks.org>
+ * 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_CodecPort {
+	import from IPL4asp_PortType all;
+	import from IPL4asp_Types all;
+	import from GTPU_Types all;
+	import from Misc_Helpers all;
+
+	/* identifies a remote peer (sender or receiver) */
+	type record Gtp1uPeer {
+		ConnectionId	connId,
+		HostName	remName,
+		PortNumber	remPort
+	}
+
+	/* Decoded GTP1U (User Plane), used in send and receive direction */
+	type record Gtp1uUnitdata {
+		Gtp1uPeer	peer,
+		PDU_GTPU	gtpu
+	}
+
+	/* dual-faced port on top of IPL4asp; ASP_Event passed through transparently */
+	type port GTPU_PT message {
+		out	Gtp1uUnitdata;
+		in	Gtp1uUnitdata,
+			ASP_ConnId_ReadyToRelease,
+			ASP_Event;
+	} with { extension "user IPL4asp_PT
+		out(Gtp1uUnitdata -> ASP_SendTo: function(f_enc_Gtp1uUD))
+		in(ASP_RecvFrom -> Gtp1uUnitdata: function(f_dec_Gtp1uUD);
+		   ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple;
+		   ASP_Event -> ASP_Event: simple)" }
+
+	function f_enc_Gtp1uUD(in Gtp1uUnitdata in_ud, out ASP_SendTo out_ud) {
+		out_ud.connId := in_ud.peer.connId;
+		out_ud.remName := in_ud.peer.remName;
+		out_ud.remPort := in_ud.peer.remPort;
+		out_ud.proto := { udp := {} };
+		out_ud.msg := enc_PDU_GTPU(in_ud.gtpu);
+	} with { extension "prototype(fast)" };
+
+	function f_dec_Gtp1uUD(in ASP_RecvFrom in_ud, out Gtp1uUnitdata out_ud) {
+		out_ud.peer.connId := in_ud.connId;
+		out_ud.peer.remName := in_ud.remName;
+		out_ud.peer.remPort := in_ud.remPort;
+		out_ud.gtpu := dec_PDU_GTPU(in_ud.msg);
+	} with { extension "prototype(fast)" };
+
+}
diff --git a/library/GTPv1U_CodecPort_CtrlFunct.ttcn b/library/GTPv1U_CodecPort_CtrlFunct.ttcn
new file mode 100644
index 0000000..3a86fc9
--- /dev/null
+++ b/library/GTPv1U_CodecPort_CtrlFunct.ttcn
@@ -0,0 +1,13 @@
+module GTPv1U_CodecPort_CtrlFunct {
+
+  import from GTPv1U_CodecPort all;
+  import from IPL4asp_Types all;
+
+  external function f_GTPU_listen(
+    inout GTPU_PT portRef,
+    in HostName locName,
+    in PortNumber locPort,
+    in ProtoTuple proto,
+    in OptionList options := {}
+  ) return Result;
+}
diff --git a/library/GTPv1U_CodecPort_CtrlFunctDef.cc b/library/GTPv1U_CodecPort_CtrlFunctDef.cc
new file mode 100644
index 0000000..49f74ce
--- /dev/null
+++ b/library/GTPv1U_CodecPort_CtrlFunctDef.cc
@@ -0,0 +1,17 @@
+#include "IPL4asp_PortType.hh"
+#include "IPL4asp_PT.hh"
+#include "GTPv1U_CodecPort.hh"
+
+namespace GTPv1U__CodecPort__CtrlFunct {
+
+  IPL4asp__Types::Result f__GTPU__listen(
+    GTPv1U__CodecPort::GTPU__PT& portRef,
+    const IPL4asp__Types::HostName& locName,
+    const IPL4asp__Types::PortNumber& locPort,
+    const IPL4asp__Types::ProtoTuple& proto,
+    const IPL4asp__Types::OptionList& options)
+  {
+    return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options);
+  }
+
+}
diff --git a/library/GTPv1U_Templates.ttcn b/library/GTPv1U_Templates.ttcn
new file mode 100644
index 0000000..a31e1d2
--- /dev/null
+++ b/library/GTPv1U_Templates.ttcn
@@ -0,0 +1,167 @@
+/* GTPv1-U Templates in TTCN-3
+ * (C) 2018 Harald Welte <laforge@gnumonks.org>
+ * contributions by sysmocom - s.f.m.c. GmbH
+ * 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_Templates {
+
+	import from General_Types all;
+	import from Osmocom_Types all;
+	import from GTPU_Types all;
+	import from GTPv1U_CodecPort all;
+
+	template (present) PDU_GTPU tr_GTP1U_PDU(template (present) OCT1 msg_type,
+						 template (present) OCT4 teid,
+						 template (present) GTPU_IEs ies := ?) := {
+		pn_bit := ?,
+		s_bit := ?,
+		e_bit := ?,
+		spare := ?,
+		/* Protocol Type flag (PT) shall be set to '1' in GTP */
+		pt := '1'B,
+		/* Version shall be set to decimal 1 ('001'). */
+		version := '001'B,
+		messageType := msg_type,
+		lengthf := ?,
+		teid := teid,
+		opt_part := *,
+		gtpu_IEs := ies
+	}
+
+	function f_GTPU_s_bit(template (omit) uint16_t seq) return BIT1 {
+		if (istemplatekind(seq, "omit")) {
+			return '0'B;
+		}
+		return '1'B;
+	}
+
+	function f_GTPU_opt_part(template (omit) uint16_t seq) return template (omit) GTPU_Header_optional_part {
+		if (istemplatekind(seq, "omit")) {
+			return omit;
+		}
+		var GTPU_Header_optional_part ret := {
+			sequenceNumber := int2oct(valueof(seq), 2),
+			npduNumber := '00'O,
+			nextExtHeader := '00'O,
+			gTPU_extensionHeader_List := omit
+		};
+		return ret;
+	}
+
+	/* generalized GTP-U send template */
+	template (value) PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, template (omit) uint16_t seq, OCT4 teid, GTPU_IEs ies) := {
+		/* N-PDU Number flag (PN): the GTP-U header contains a meaningful N-PDU Number field if the PN
+		 * flag is set to 1. */
+		pn_bit := '0'B,	/* we assume the encoder overwrites this if an optional part is given */
+		/* If the Sequence Number flag (S) is set to '1' the sequence number field is present and
+		 * meaningful otherwise it is set to '0'. For GTP-U messages Echo Request, Echo Response,
+		 * Error Indication and Supported Extension Headers Notification, the S flag shall be set to '1'.
+		 *
+		 * Note that the caller must ensure that these conditions hold.
+		 * The caller can either pass a sequence number (we set s_bit to '1'B) when appropriate,
+		 * or may omit the sequence number (we set s_bit to '0'B). */
+		s_bit := f_GTPU_s_bit(seq),
+		/* Extension header presence */
+		e_bit := '0'B,
+		spare := '0'B,
+		/* Protocol Type flag (PT) shall be set to '1' in GTP */
+		pt := '1'B,
+		/* Version shall be set to decimal 1 ('001'). */
+		version := '001'B,
+		messageType := msg_type,
+		lengthf := 0,	/* we assume encoder overwrites this */
+		teid := teid,
+		opt_part := f_GTPU_opt_part(seq),
+		gtpu_IEs := ies
+	}
+
+	template (present) Gtp1uUnitdata tr_GTPU_MsgType(template (present) Gtp1uPeer peer,
+							 template (present) OCT1 msg_type,
+							 template (present) OCT4 teid) := {
+		peer := peer,
+		gtpu := tr_GTP1U_PDU(msg_type, teid)
+	}
+
+
+	/* template matching reception of GTP-U echo-request/response */
+	template (present) Gtp1uUnitdata tr_GTPU_PING(template (present) Gtp1uPeer peer) := tr_GTPU_MsgType(peer, '01'O, '00000000'O);
+	template (present) Gtp1uUnitdata tr_GTPU_PONG(template (present) Gtp1uPeer peer) := tr_GTPU_MsgType(peer, '02'O, '00000000'O);
+
+	/* template matching reception of GTP-U GPDU */
+	template GTPU_IEs t_GPDU(template (present) octetstring data) := {
+		g_PDU_IEs := {
+			data := data
+		}
+	}
+	template (present) Gtp1uUnitdata tr_GTPU_GPDU(template (present) Gtp1uPeer peer,
+						      template (present) OCT4 teid,
+						      template (present) octetstring data := ?) := {
+		peer := peer,
+		gtpu := tr_GTP1U_PDU('FF'O, teid, t_GPDU(data))
+	}
+
+	template (present) GTPU_IEs ts_UEchoReqPDU := {
+		echoRequest_IEs := {
+			private_extension_gtpu := omit
+		}
+	}
+
+	/* master template for sending a GTP-C echo request */
+	template (value) Gtp1uUnitdata ts_GTPU_PING(Gtp1uPeer peer, uint16_t seq) := {
+		peer := peer,
+		gtpu := ts_GTP1U_PDU('01'O, seq, '00000000'O, valueof(ts_UEchoReqPDU))
+	}
+
+	template GTPU_IEs ts_UEchoRespPDU(OCT1 restart_counter) := {
+		echoResponse_IEs := {
+			recovery_gtpu := {
+				type_gtpu := '00'O, /* we assume encoder fixes? */
+				restartCounter := restart_counter
+			},
+			private_extension_gtpu := omit
+		}
+	}
+
+	/* master template for sending a GTP-U echo response */
+	template (present) Gtp1uUnitdata ts_GTPU_PONG(Gtp1uPeer peer, uint16_t seq, OCT1 rest_ctr) := {
+		peer := peer,
+		gtpu := ts_GTP1U_PDU('02'O, seq, '00000000'O, valueof(ts_UEchoRespPDU(rest_ctr)))
+	}
+
+	template (value) GSNAddress_gtpu ts_UGsnAddr(octetstring ip_addr) := {
+		type_gtpu := '85'O,
+		lengthf := lengthof(ip_addr),
+		gSNAddressValue := ip_addr
+	}
+
+	template (value) TeidDataI_gtpu ts_UteidDataI(OCT4 teid) := {
+		type_gtpu := '10'O,
+		teidDataI := teid
+	}
+
+	template (value)  GTPU_IEs ts_UErrorIndication(OCT4 teid, octetstring gsn_addr) := {
+		errorIndication_IEs := {
+			teidDataI_gtpu := ts_UteidDataI(teid),
+			gSNAddress_gtpu := ts_UGsnAddr(gsn_addr),
+			private_extension_gtpu := omit
+		}
+	}
+
+	/* master template for sending a GTP-U Error indication */
+	template (value) Gtp1uUnitdata ts_GTPU_ErrorIndication(Gtp1uPeer peer, uint16_t seq, OCT4 teid, octetstring gsn_addr) := {
+		peer := peer,
+		gtpu := ts_GTP1U_PDU('1A'O, seq, '00000000'O, valueof(ts_UErrorIndication(teid, gsn_addr)))
+	}
+
+	/* master template for sending a GTP-U user plane data */
+	template (value) Gtp1uUnitdata ts_GTP1U_GPDU(Gtp1uPeer peer, template (omit) uint16_t seq, OCT4 teid, octetstring data) := {
+		peer := peer,
+		gtpu := ts_GTP1U_PDU('FF'O, seq, teid, { g_PDU_IEs := { data := data }})
+	}
+}
diff --git a/library/GTPv2_CodecPort.ttcn b/library/GTPv2_CodecPort.ttcn
index e9cf57e..0c4e9d3 100644
--- a/library/GTPv2_CodecPort.ttcn
+++ b/library/GTPv2_CodecPort.ttcn
@@ -15,7 +15,7 @@
 	import from GTPv2_Types all;
 
 	/* identifies a remote peer (sender or receiver) */
-	type record GtpPeer {
+	type record Gtp2cPeer {
 		ConnectionId	connId,
 		HostName	remName,
 		IPL4asp_Types.PortNumber	remPort
@@ -23,7 +23,7 @@
 
 	/* Decoded GTP2C (Control Plane), used in send and receive direction */
 	type record Gtp2cUnitdata {
-		GtpPeer		peer,
+		Gtp2cPeer	peer,
 		PDU_GTPCv2	gtpc
 	}
 
diff --git a/library/GTPv2_Emulation.ttcn b/library/GTPv2_Emulation.ttcn
index 240cce4..054bd4b 100644
--- a/library/GTPv2_Emulation.ttcn
+++ b/library/GTPv2_Emulation.ttcn
@@ -62,7 +62,7 @@
 	var Gtp2EmulationCfg g_gtp2_cfg;
 
 	/* State */
-	var GtpPeer g_peer;
+	var Gtp2cPeer g_peer;
 	var integer g_gtp2c_id;
 	var OCT1 g_restart_ctr;
 	var uint16_t g_c_seq_nr;