/* dual-faced port sitting on top of IPL4_asp UDP to encode/decode GTP
 * (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 GTP_CodecPort {
	import from IPL4asp_PortType all;
	import from IPL4asp_Types all;
	import from GTPC_Types all;
	import from GTPU_Types all;

	/* identifies a remote peer (sender or receiver) */
	type record GtpPeer {
		ConnectionId	connId,
		HostName	remName,
		PortNumber	remPort
	}

	/* Decoded GTP1C (Control Plane), used in send and receive direction */
	type record Gtp1cUnitdata {
		GtpPeer		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;
		in	Gtp1cUnitdata,
			ASP_ConnId_ReadyToRelease,
			ASP_Event;
	} with { extension "user IPL4asp_PT
		out(Gtp1cUnitdata -> ASP_SendTo: function(f_enc_Gtp1cUD))
		in(ASP_RecvFrom -> Gtp1cUnitdata: function(f_dec_Gtp1cUD);
		   ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple;
		   ASP_Event -> ASP_Event: simple)" }

	private function f_enc_Gtp1cUD(in Gtp1cUnitdata 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_GTPC(in_ud.gtpc);
	} with { extension "prototype(fast)" };

	private function f_dec_Gtp1cUD(in ASP_RecvFrom in_ud, out Gtp1cUnitdata 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.gtpc := dec_PDU_GTPC(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)" };

}
