module Iuh_Emulation {

/* Iuh Emulation, runs on top of Iuh_CodecPort.  It multiplexes/demultiplexes
 * HNBAP and RUA.
 *
 * The Iuh_Emulation.main() function processes Iuh primitives from the Iuh
 * socket via the Iuh_CodecPort, and dispatches them to HNBAP/RUA ports.
 *
 * (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 * 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
 */

import from Iuh_CodecPort all;
import from Iuh_CodecPort_CtrlFunct all;
import from HNBAP_Types all;
import from HNBAP_Constants all;
import from HNBAP_PDU_Contents all;
import from HNBAP_PDU_Descriptions all;
import from HNBAP_IEs all;
import from HNBAP_Templates all;
import from RUA_Types all;
import from RUA_Constants all;
import from RUA_PDU_Contents all;
import from RUA_PDU_Descriptions all;
import from RUA_IEs all;
import from RUA_Templates all;
import from Iuh_Types all;
import from SCTP_Templates all;

import from General_Types all;
import from Misc_Helpers all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from DNS_Helpers all;

/* General "base class" component definition, of which specific implementations
 * derive themselves by means of the "extends" feature */
type component Iuh_ConnHdlr {
	port HNBAP_PT HNBAP;
	port RUA_PT RUA;
};

type enumerated IUHEM_EventUpDown {
	IUHEM_EVENT_DOWN,
	IUHEM_EVENT_UP
}

/* an event indicating us whether or not a connection is physically up or down. */
type union IUHEM_Event {
	IUHEM_EventUpDown	up_down
}

type port HNBAP_PT message {
	inout HNBAP_PDU, IUHEM_Event;
} with { extension "internal" };
type port RUA_PT message {
	inout RUA_PDU, IUHEM_Event;
} with { extension "internal" };

type component Iuh_Emulation_CT {
	/* Port facing to the SCTP SUT */
	port Iuh_CODEC_PT Iuh;
	/* Port facing to user upper side stack: */
	port HNBAP_PT HNBAP;
	port RUA_PT RUA;

	var Iuh_conn_parameters g_pars;
	var charstring g_Iuh_id;
	var integer g_self_conn_id := -1;
	var IPL4asp_Types.ConnectionId g_last_conn_id := -1; /* server only */
}

type record Iuh_conn_parameters {
	HostName remote_ip,
	PortNumber remote_sctp_port,
	HostName local_ip,
	PortNumber local_sctp_port
}

function tr_Iuh_RecvFrom_R(template Iuh_PDU msg)
runs on Iuh_Emulation_CT return template Iuh_RecvFrom {
	var template Iuh_RecvFrom mrf := {
		connId := ?,
		remName := ?,
		remPort := ?,
		locName := ?,
		locPort := ?,
		msg := msg
	}
	return mrf;
}

private function emu_is_server() runs on Iuh_Emulation_CT return boolean {
	return g_pars.remote_sctp_port == -1
}

/* Resolve TCP/IP connection identifier depending on server/client mode */
private function f_iuh_conn_id() runs on Iuh_Emulation_CT
return IPL4asp_Types.ConnectionId {
	var IPL4asp_Types.ConnectionId conn_id;

	if (not emu_is_server()) {
		conn_id := g_self_conn_id;
	} else {
		conn_id := g_last_conn_id;
	}

	if (conn_id == -1) { /* Just to be sure */
		f_shutdown(__FILE__, __LINE__, fail, "Connection is not established");
	}

	return conn_id;
}

private function f_send_IUHEM_Event(template (value) IUHEM_Event evt) runs on Iuh_Emulation_CT {
	if (HNBAP.checkstate("Connected")) {
		HNBAP.send(evt);
	}
}

function main(Iuh_conn_parameters p, charstring id) runs on Iuh_Emulation_CT {
	var Result res;
	g_pars := p;
	g_Iuh_id := id;

	map(self:Iuh, system:Iuh_CODEC_PT);
	if (emu_is_server()) {
		res := Iuh_CodecPort_CtrlFunct.f_IPL4_listen(Iuh, p.local_ip, p.local_sctp_port,
							     { sctp := valueof(ts_SctpTuple) });
	} else {
		res := Iuh_CodecPort_CtrlFunct.f_IPL4_connect(Iuh, p.remote_ip, p.remote_sctp_port,
							      p.local_ip, p.local_sctp_port, -1,
							      { sctp := valueof(ts_SctpTuple) });
	}
	if (not ispresent(res.connId)) {
		f_shutdown(__FILE__, __LINE__, fail, "Could not connect Iuh socket, check your configuration");
	}
	g_self_conn_id := res.connId;

	/* notify user about SCTP establishment */
	if (p.remote_sctp_port != -1) {
		f_send_IUHEM_Event(IUHEM_Event:{up_down:=IUHEM_EVENT_UP});
	}

	while (true) {
		var Iuh_RecvFrom mrf;
		var HNBAP_PDU hnbap_msg;
		var RUA_PDU rua_msg;
		var ASP_Event asp_evt;

		alt {
		/* HNBAP from client: pass on transparently */
		[] HNBAP.receive(HNBAP_PDU:?) -> value hnbap_msg {
			/* Pass message through */
			Iuh.send(t_Iuh_Send_HNBAP(f_iuh_conn_id(), hnbap_msg));
			}
		/* RUA from client: pass on transparently */
		[] RUA.receive(RUA_PDU:?) -> value rua_msg {
			/* Pass message through */
			Iuh.send(t_Iuh_Send_RUA(f_iuh_conn_id(), rua_msg));
			}

		/* Iuh received from peer (HNBGW or HnodeB) */
		[] Iuh.receive(tr_Iuh_RecvFrom_R(?)) -> value mrf {
			if (not match(mrf.connId, f_iuh_conn_id())) {
				f_shutdown(__FILE__, __LINE__, fail, log2str("Received message from unexpected conn_id!", mrf));
			}

			if (match(mrf, t_Iuh_RecvFrom_HNBAP(?))) {
				HNBAP.send(mrf.msg.hnbap);
			} else if (match(mrf, t_Iuh_RecvFrom_RUA(?))) {
				RUA.send(mrf.msg.rua);
			} else {
				/* TODO: special handling, as it contains multiple HNB connection ids */
				f_shutdown(__FILE__, __LINE__, fail, log2str("UNEXPECTED MESSAGE RECEIVED!", mrf));
			}
		}
		[] Iuh.receive(tr_SctpAssocChange) { }
		[] Iuh.receive(tr_SctpPeerAddrChange)  { }

		/* server only */
		[] Iuh.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
			if (not emu_is_server()) {
				f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected event receiver in client mode", asp_evt));
			}
			g_last_conn_id := asp_evt.connOpened.connId;
			log("Established a new Iuh connection (conn_id=", g_last_conn_id, ")");

			f_send_IUHEM_Event(IUHEM_Event:{up_down:=IUHEM_EVENT_UP}); /* TODO: send g_last_conn_id */
		}

		[] Iuh.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
			log("Iuh: Closed");
			g_self_conn_id := -1;
			f_send_IUHEM_Event(IUHEM_Event:{up_down:=IUHEM_EVENT_DOWN});  /* TODO: send asp_evt.connClosed.connId */
			if (not emu_is_server()) {
				self.stop;
			}
		}
		}
	}
}

}
