/* 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;
	import from Misc_Helpers all;

	modulepar {
		SystemUnderTest mp_pl_SystemUnderTest := SGSN;
	}

	/* 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, pl_SystemUnderTest := mp_pl_SystemUnderTest);
		if (lengthof(in_ud.msg) != out_ud.gtpc.lengthf + 8) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
				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)" };

}
