module SABP_Adapter {

/* SABP Adapter layer, sitting on top of SABP_CodecPort.
 * test suites can 'inherit' in order to have a SABP connection to the IUT which they're testing
 *
 * (C) 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 SABP_Types all;
import from SABP_PDU_Descriptions all;
import from SABP_Templates all;
import from SABP_CodecPort all;
import from SABP_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from Socket_API_Definitions all;

const integer SABP_HDR_LEN := 3;

const integer NUM_SABP := 3;

type component SABP_Adapter_CT {
	/* down-facing port to SABP Codec port */
	port SABP_CODEC_PT SABP[NUM_SABP];
	var IPL4asp_Types.ConnectionId g_sabp_conn_id[NUM_SABP] := { -1, -1, -1 };
}

/*! parse a single APER length determinant. Return -1 if input insufficient or -2 if invalid */
private function f_aper_len_det(in octetstring stream, out integer len_len) return integer {
	if (lengthof(stream) < 1) {
		return -1;
	}

	select (stream[0] and4b 'C0'O) {
	case ('00'O) {
		/* total length is encoded in this octet */
		len_len := 1;
		return oct2int(stream[0]);
		}
	case ('80'O) {
		/* total length (up to 16k) encoded in two octets */
		if (lengthof(stream) < 2) {
			return -1;
		}
		len_len := 2;
		return (oct2int(stream[0] and4b '3F'O) * 256) + oct2int(stream[1]);
		}
	case ('C0'O) {
		/* total length not known, encoded in chunks; first chunk length now known */
		len_len := 1;
		return oct2int(stream[0] and4b '3F'O) * 16384;
		}
	case else {
		return -2;
		}

	}
}

/* The callback function has to return the length of the message if completely received. It has to return
 * "-1" if the length cannot be determined. If the message is incomplete, but the length can be
 * determined, then the function should return the length. In this case the callback function will not be
 * called again for the given message - possibly increasing the performance. Alternatively the function may
 * always return "-1" when the message is incomplete.
 * If the callback function detects that the it will be impossible to determine the length of the message,
 * even receiving more octets, should return "-2". In this case the connection will be closed and the
 * length calculation error will be reported. */
private function f_APER_getMsgLen(in octetstring stream, inout Socket_API_Definitions.ro_integer args) return integer {
	var integer stream_len := lengthof(stream);
	var integer hdr_len := args[0];
	var octetstring stream_nohdr;
	var integer len, len_len;

	if (stream_len < hdr_len + 1) {
		return -1;
	}
	stream_nohdr := substr(stream, hdr_len, stream_len-hdr_len);

	len := f_aper_len_det(stream_nohdr, len_len);
	if (len < 0) {
		/* error: return to caller */
		return len;
	}
	if (len < 16384) {
		/* full length is known: return to caller */
		return hdr_len + len_len + len;
	} else {
		/* 'cursor' to next length indicator */
		var integer cur := hdr_len + len_len + len;
		/* iterate the whole chain of chunks */
		while (true) {
			if (stream_len < cur + 1) {
				return -1;
			}
			len := f_aper_len_det(substr(stream, cur, stream_len-cur), len_len);
			if (len < 0) {
				/* error: return to caller */
				return len;
			}
			if (len < 16384) {
				/* final chunk: segment with less than 16384 bytes */
				return cur + len_len + len;
			} else {
				/* point to next chunk */
				cur := cur + len_len + len;
			}
		}
	}
	/* not reached */
	return -2;
}

private function f_set_tcp_segmentation(integer idx) runs on SABP_Adapter_CT {
	/* Set function for dissecting the binary stream into packets */
	var f_IPL4_getMsgLen vl_f := refers(f_APER_getMsgLen);
	/* Offset: 1, size of length: 3, delta: 4, multiplier: 1, big-endian */
	SABP_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(SABP[idx], g_sabp_conn_id[idx], vl_f, {SABP_HDR_LEN});
}

function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
		   charstring local_host, IPL4asp_Types.PortNumber local_port, integer idx := 0)
runs on SABP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:SABP[idx], system:SABP);
	res := SABP_CodecPort_CtrlFunct.f_IPL4_connect(SABP[idx], remote_host, remote_port,
							local_host, local_port, 0, { tcp :={} });
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect to SABP port, check your configuration");
		mtc.stop;
	}
	g_sabp_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 SABP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:SABP[idx], system:SABP);
	res := SABP_CodecPort_CtrlFunct.f_IPL4_listen(SABP[idx], local_host, local_port, { tcp:={} });
	g_sabp_conn_id[idx] := res.connId;

	f_set_tcp_segmentation(idx);
}

function f_sabp_send(template (value) SABP_PDU pdu, integer idx := 0) runs on SABP_Adapter_CT {
	SABP[idx].send(ts_SABP_Send(g_sabp_conn_id[idx], pdu));
}

function f_sabp_exp(template SABP_PDU exp, integer idx := 0) runs on SABP_Adapter_CT return SABP_PDU {
	var SABP_RecvFrom rf;
	SABP[idx].receive(tr_SABP_Recv(g_sabp_conn_id[idx], exp)) -> value rf;
	return rf.msg;
}


}
