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);
	if (g_cbsp_conn_id[idx] != -1) {
		CBSP_CodecPort_CtrlFunct.f_IPL4_close(CBSP[idx], g_cbsp_conn_id[idx], {tcp := {}});
		g_cbsp_conn_id[idx] := -1;
	}
	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 ",
			"{remote ", remote_host, ":", remote_port, " local ", local_host, ":", local_port, "}");
		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);
	if (g_cbsp_conn_id[idx] != -1) {
		CBSP_CodecPort_CtrlFunct.f_IPL4_close(CBSP[idx], g_cbsp_conn_id[idx], {tcp := {}});
		g_cbsp_conn_id[idx] := -1;
	}
	res := CBSP_CodecPort_CtrlFunct.f_IPL4_listen(CBSP[idx], local_host, local_port, { tcp:={} });
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not bind to CBSP port, check your configuration ",
			   "{local ", local_host, ":", local_port, "}");
		mtc.stop;
	}
	g_cbsp_conn_id[idx] := res.connId;

	f_set_tcp_segmentation(idx);
}

function f_wait_client_connect(integer idx := 0) runs on CBSP_Adapter_CT {
	var IPL4asp_Types.PortEvent rx_event;
	CBSP[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_cbsp_conn_id[idx] := rx_event.connOpened.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;
}


}
