module SBC_AP_Adapter {

/* SBC_AP Adapter layer, sitting on top of SBC_AP_CodecPort.
 * test suites can 'inherit' in order to have a SBC_AP 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 SBC_AP_Types all;
import from SBC_AP_PDU_Descriptions all;
import from SBC_AP_Templates all;
import from SBC_AP_CodecPort all;
import from SBC_AP_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from Socket_API_Definitions all;
import from Misc_Helpers all;


const integer SBC_AP_HDR_LEN := 3;

const integer NUM_SBC_AP := 3;

type component SBC_AP_Adapter_CT {
	/* down-facing port to SBC_AP Codec port */
	port SBC_AP_CODEC_PT SBC_AP[NUM_SBC_AP];
	var IPL4asp_Types.ConnectionId g_SBC_AP_conn_id[NUM_SBC_AP] := { -1, -1, -1 };
}

private template Socket_API_Definitions.PortEvent tr_SctpAssocChange_COMM_UP(IPL4asp_Types.ConnectionId id) := {
	sctpEvent := {
		sctpAssocChange := {
			clientId := id,
			proto := {
				sctp := ?
			},
			sac_state := SCTP_COMM_UP
		}
	}
}

function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
		   charstring local_host, IPL4asp_Types.PortNumber local_port, integer idx := 0)
runs on SBC_AP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:SBC_AP[idx], system:SBC_AP);
	res := SBC_AP_CodecPort_CtrlFunct.f_IPL4_connect(SBC_AP[idx], remote_host, remote_port,
							local_host, local_port, 0, { sctp := valueof(ts_SBC_AP_SctpTuple) });
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect to SBC_AP port, check your configuration");
		mtc.stop;
	}
	g_SBC_AP_conn_id[idx] := res.connId;
	timer Tcommup := 10.0;
	Tcommup.start;
	alt {
	[] SBC_AP[idx].receive(tr_SctpAssocChange_COMM_UP(g_SBC_AP_conn_id[idx])) {}
	[] Tcommup.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting SCTP_COMM_UP");
	}
	}
}

/* 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 SBC_AP_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:SBC_AP[idx], system:SBC_AP);
	res := SBC_AP_CodecPort_CtrlFunct.f_IPL4_listen(SBC_AP[idx], local_host, local_port, { sctp := valueof(ts_SBC_AP_SctpTuple) });
	g_SBC_AP_conn_id[idx] := res.connId;
}

function f_wait_client_connect(integer idx := 0) runs on SBC_AP_Adapter_CT {
	var IPL4asp_Types.PortEvent rx_event;
	SBC_AP[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_SBC_AP_conn_id[idx] := rx_event.connOpened.connId;
	}
	timer Tcommup := 10.0;
	Tcommup.start;
	alt {
	[] SBC_AP[idx].receive(tr_SctpAssocChange_COMM_UP(g_SBC_AP_conn_id[idx])) {}
	[] Tcommup.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting SCTP_COMM_UP");
	}
	}
}

function f_SBC_AP_send(template (value) SBC_AP_PDU pdu, integer idx := 0) runs on SBC_AP_Adapter_CT {
	SBC_AP[idx].send(ts_SBC_AP_Send(g_SBC_AP_conn_id[idx], pdu));
}

function f_SBC_AP_exp(template SBC_AP_PDU exp, integer idx := 0) runs on SBC_AP_Adapter_CT return SBC_AP_PDU {
	var SBC_AP_RecvFrom rf;
	SBC_AP[idx].receive(tr_SBC_AP_Recv(g_SBC_AP_conn_id[idx], exp)) -> value rf;
	return rf.msg;
}


}
