module OPCAP_CLIENT_Tests {

import from OPCAP_Adapter all;
import from OPCAP_Types all;
import from OPCAP_Templates all;

import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from Osmocom_Types all;
import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;
import from Socket_API_Definitions all;

type record IpPort {
	charstring ip,
	integer udp_port
};

modulepar {
	/* local IP address listening for OPCAP connections */
	charstring mp_local_opcap_ip := "127.0.0.1";
	/* local TCP base port for inbound OPCAP connections */
	integer mp_local_opcap_port := 5000;

	/* IP + port for simulating user traffic */
	IpPort mp_traffic_a := { "127.0.0.23", 44423 };
	IpPort mp_traffic_b := { "127.0.0.42", 44442 };
};

type component test_CT extends OPCAP_Adapter_CT {
	timer g_Tguard := 30.0;

	port TELNETasp_PT VTY;

	/* port to generate IP traffic that may or may not be captured */
	port IPL4asp_PT IP;
	var integer g_traffic_conn_id;
};

private altstep as_Tguard() runs on test_CT {
[] g_Tguard.timeout {
	setverdict(fail, "global guard timeout");
	mtc.stop;
	}
}

/* initialize one of the OPCAP servers, wait for client to connect */
private function f_init_one_srv(integer idx, template (present) uint32_t linktype) runs on test_CT {
	/* start guard timer */
	activate(as_Tguard());
	g_Tguard.start;
	log("Waiting for client-", idx, " connection...");
	/* wait for connection */
	f_bind(mp_local_opcap_ip, mp_local_opcap_port+idx, idx);
	f_wait_client_connect(idx);
	/* wait for file header */
	f_opcap_exp(tr_OPCAP_FILE_HDR(linktype), idx);
};


/* global initialization */
private function f_init() runs on test_CT {
	map(self:VTY, system:VTY);
	f_vty_set_prompts(VTY);
	f_vty_transceive(VTY, "enable");

	map(self:IP, system:IP);
	var IPL4asp_Types.Result res

	/* 0 -> 1 */
	res := f_IPL4_connect(IP, mp_traffic_b.ip, mp_traffic_b.udp_port,
			      mp_traffic_a.ip, mp_traffic_a.udp_port, -1, { udp:={} });
	g_traffic_conn_id := res.connId;
}

/* generate user traffic from A -> B */
function f_trafic_pkt_ab(octetstring payload) runs on test_CT {
	IP.send(ASP_Send:{g_traffic_conn_id, omit, payload})
}

/* expect a specified UDP payload on the OPCAP connection 'idx' */
function f_opcap_exp_udp(octetstring udp_payload, integer idx) runs on test_CT {
	var octetstring rx_tail;
	var integer udp_payload_len, rx_pdu_len;
	var OPCAP_PDU rx_pdu;

	udp_payload_len := lengthof(udp_payload);

	/* sadly I couldn't figure out how to create an octetstring template
	 * for 'match an octetstring ending in 'udp_payload' */
	rx_pdu := f_opcap_exp(tr_OPCAP_PKT(?), idx);
	rx_pdu_len := lengthof(rx_pdu.u.packet.payload);
	rx_tail := substr(rx_pdu.u.packet.payload, rx_pdu_len - udp_payload_len, udp_payload_len);
	if (rx_tail != udp_payload) {
		log("captured UDP payload: ", rx_tail, " but expected: ", udp_payload);
		setverdict(fail);
	} else {
		setverdict(pass);
	}
}

/* create an additional pcap-store-connection via the VTY */
function f_vty_create_addl_connection(integer idx) runs on test_CT
{
	f_vty_config3(VTY, { "client", "pcap-store-connectio second-" & int2str(idx) },
			{ "server ip " & mp_local_opcap_ip,
			  "server port " & int2str(mp_local_opcap_port + idx),
			  "connect" }
			);
}



/* wait for inbound client connection and reception of link header */
testcase TC_connect_rx_hdr() runs on test_CT
{
	f_init();
	f_init_one_srv(0, ?);
	setverdict(pass);
}

/* check if client connection is re-started after a close */
testcase TC_reconnect(integer idx := 0) runs on test_CT
{
	f_init();
	f_init_one_srv(idx, ?);
	f_sleep(2.0);

	log("Disconnecting client-", idx);
	f_disconnect(idx);

	f_wait_client_connect(idx);
	f_opcap_exp(tr_OPCAP_FILE_HDR(?), idx);
	setverdict(pass);
}

/* capture a packet that's within the filter */
testcase TC_capture() runs on test_CT
{
	f_init();
	f_init_one_srv(0, ?);

	for (var integer i := 0; i < 10; i := i + 1) {
		var octetstring udp_payload;

		/* we assume 1400 is low enough to avoid IP fragmentation */
		udp_payload := f_rnd_octstring(f_rnd_int(1400));
		f_trafic_pkt_ab(udp_payload);

		f_opcap_exp_udp(udp_payload, 0);
	}
}

/* wait for inbound client connections and reception of link header */
testcase TC_multi_connect_rx_hdr() runs on test_CT
{
	f_init();
	f_init_one_srv(0, ?);
	f_vty_create_addl_connection(1);
	f_init_one_srv(1, ?);
	setverdict(pass);
}

/* ensure a packet that's within the filter is sent to secondary clients */
testcase TC_multi_capture() runs on test_CT
{
	f_init();
	f_init_one_srv(0, ?);
	f_vty_create_addl_connection(1);
	f_init_one_srv(1, ?);

	for (var integer i := 0; i < 10; i := i + 1) {
		var octetstring udp_payload;

		/* we assume 1400 is low enough to avoid IP fragmentation */
		udp_payload := f_rnd_octstring(f_rnd_int(1400));
		f_trafic_pkt_ab(udp_payload);

		/* expect packet to arrive on both simulated servers */
		f_opcap_exp_udp(udp_payload, 0);
		f_opcap_exp_udp(udp_payload, 1);
	}
}

/* TODO: ensure a packet outside the filter is dropped */
/* TODO: capture of truncated packet */
/* TODO: stall the receive window */
/* TODO: different link type (ethernet, not SLL) */


control {
	execute( TC_connect_rx_hdr() );
	execute( TC_reconnect() );
	execute( TC_capture() );
	execute( TC_multi_connect_rx_hdr() );
	execute( TC_multi_capture() );
};


};
