module OPCAP_Adapter {

/* OPCAP Adapter layer, sitting on top of OPCAP_CodecPort.
 * test suites can 'inherit' in order to have a OPCAP connection to the IUT which they're testing
 *
 * (C) 2021 by 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.
 */


import from Osmocom_Types all;
import from General_Types all;
import from OPCAP_Types all;
import from OPCAP_Templates all;
import from OPCAP_CodecPort all;
import from OPCAP_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from Socket_API_Definitions all;

const integer NUM_OPCAP := 3;

type component OPCAP_Adapter_CT {
	/* down-facing port to OPCAP Codec port */
	port OPCAP_CODEC_PT OPCAP[NUM_OPCAP];
	var IPL4asp_Types.ConnectionId g_opcap_conn_id[NUM_OPCAP] := { -1, -1, -1 };
}

private function f_set_tcp_segmentation(integer idx) runs on OPCAP_Adapter_CT {
	/* Set function for dissecting the binary stream into packets */
	var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
	/* Offset: 2, size of length: 2, delta: 4, multiplier: 1, big-endian */
	OPCAP_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(OPCAP[idx], g_opcap_conn_id[idx], vl_f, {2, 2, 4, 1, 0});
}

function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
		   charstring local_host, IPL4asp_Types.PortNumber local_port, integer idx := 0)
runs on OPCAP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:OPCAP[idx], system:OPCAP);
	if (g_opcap_conn_id[idx] != -1) {
		OPCAP_CodecPort_CtrlFunct.f_IPL4_close(OPCAP[idx], g_opcap_conn_id[idx], {tcp := {}});
		g_opcap_conn_id[idx] := -1;
	}
	res := OPCAP_CodecPort_CtrlFunct.f_IPL4_connect(OPCAP[idx], remote_host, remote_port,
							local_host, local_port, 0, { tcp :={} });
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect to OPCAP port, check your configuration ",
			"{remote ", remote_host, ":", remote_port, " local ", local_host, ":", local_port, "}");
		mtc.stop;
	}
	g_opcap_conn_id[idx] := res.connId;

	f_set_tcp_segmentation(idx);
}

/* Function to use to bind to a local port as IPA server, accepting remote clients */
function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port, integer idx := 0)
runs on OPCAP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:OPCAP[idx], system:OPCAP);
	if (g_opcap_conn_id[idx] != -1) {
		OPCAP_CodecPort_CtrlFunct.f_IPL4_close(OPCAP[idx], g_opcap_conn_id[idx], {tcp := {}});
		g_opcap_conn_id[idx] := -1;
	}
	res := OPCAP_CodecPort_CtrlFunct.f_IPL4_listen(OPCAP[idx], local_host, local_port, { tcp:={} });
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not bind to OPCAP port, check your configuration ",
			   "{local ", local_host, ":", local_port, "}");
		mtc.stop;
	}
	g_opcap_conn_id[idx] := res.connId;

	f_set_tcp_segmentation(idx);
}

function f_wait_client_connect(integer idx) runs on OPCAP_Adapter_CT {
	var IPL4asp_Types.PortEvent rx_event;
	OPCAP[idx].receive(IPL4asp_Types.PortEvent:{connOpened:=?}) -> value rx_event {
		log("Connection from ", rx_event.connOpened.remName, ":", rx_event.connOpened.remPort);
		/* we want to store the client's connId, not the 'bind socket' one */
		g_opcap_conn_id[idx] := rx_event.connOpened.connId;
	}
}

function f_disconnect(integer idx) runs on OPCAP_Adapter_CT {
	OPCAP_CodecPort_CtrlFunct.f_IPL4_close(OPCAP[idx], g_opcap_conn_id[idx], {tcp := {}});
	OPCAP[idx].clear;
};

function f_opcap_send(template (value) OPCAP_PDU pdu, integer idx := 0) runs on OPCAP_Adapter_CT {
	OPCAP[idx].send(ts_OPCAP_Send(g_opcap_conn_id[idx], pdu));
}

function f_opcap_exp(template OPCAP_PDU exp, integer idx := 0) runs on OPCAP_Adapter_CT return OPCAP_PDU {
	var OPCAP_RecvFrom rf;
	OPCAP[idx].receive(tr_OPCAP_Recv(g_opcap_conn_id[idx], exp)) -> value rf;
	return rf.msg;
}


}
