module CBSP_Adapter {

/* CBSP Adapter layer, sitting on top of CBSP_CodecPort.
 * test suites can 'inherit' in order to have a CBSP connection to the IUT which they're testing
 *
 * (C) 2018-2019 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 CBSP_Types all;
import from CBSP_Templates all;
import from CBSP_CodecPort all;
import from CBSP_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from Socket_API_Definitions all;

const integer NUM_CBSP := 3;

type component CBSP_Adapter_CT {
	/* down-facing port to CBSP Codec port */
	port CBSP_CODEC_PT CBSP[NUM_CBSP];
	var IPL4asp_Types.ConnectionId g_cbsp_conn_id[NUM_CBSP] := { -1, -1, -1 };
}

private function f_set_tcp_segmentation(integer idx) runs on CBSP_Adapter_CT {
	/* Set function for dissecting the binary stream into packets */
	var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
	/* Offset: 1, size of length: 3, delta: 4, multiplier: 1, big-endian */
	CBSP_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(CBSP[idx], g_cbsp_conn_id[idx], vl_f, {1, 3, 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 CBSP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:CBSP[idx], system:CBSP);
	res := CBSP_CodecPort_CtrlFunct.f_IPL4_connect(CBSP[idx], remote_host, remote_port,
							local_host, local_port, 0, { tcp :={} });
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect to CBSP port, check your configuration");
		mtc.stop;
	}
	g_cbsp_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 CBSP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:CBSP[idx], system:CBSP);
	res := CBSP_CodecPort_CtrlFunct.f_IPL4_listen(CBSP[idx], local_host, local_port, { tcp:={} });
	g_cbsp_conn_id[idx] := res.connId;

	f_set_tcp_segmentation(idx);
}

function f_cbsp_send(template (value) CBSP_PDU pdu, integer idx := 0) runs on CBSP_Adapter_CT {
	CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], pdu));
}

function f_cbsp_exp(template CBSP_PDU exp, integer idx := 0) runs on CBSP_Adapter_CT return CBSP_PDU {
	var CBSP_RecvFrom rf;
	CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], exp)) -> value rf;
	return rf.msg;
}


}
