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

	modulepar {
		SystemUnderTest mp_pl_SystemUnderTest := SGSN;
	}

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

	/* Decoded GTP1C (Control Plane), used in send and receive direction */
	type record Gtp1cUnitdata {
		Gtp1cPeer	peer,
		PDU_GTPC	gtpc
	}

 	/* 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)" };
}
