module CCID_Tests {

/* TTCN-3 tests for USB CCID (Chip Card Interface Device)
 *
 * (C) 2018-2019 by Harald Welte <laforge@gnumonks.org>
 */

import from General_Types all;
import from Osmocom_Types all;
import from Misc_Helpers all;

import from USB_PortType all;
import from USB_Component all;

import from CCID_Types all;
import from CCID_Templates all;
import from CCID_Emulation all;

modulepar {
	USB_Device_Match mp_usb_dev_match := { vid_pid := { vid := '1d50'H, pid := '6141'H } };
	integer mp_use_slot_count := 8;
	boolean mp_test_power_off := true;
	boolean mp_quirk_resetpar_returns_slotsts := false;
}
/* global test component; manages CCID device */
type component Test_CT {
	var CCID_Emulation_CT vc_CCID;
	port USB_PT USB;
	var Slot_CT vc_SLOT[NR_SLOTS];
};

/* maximum number of slots we are supporting in the test suite */
private const integer NR_SLOTS := 16;

/***********************************************************************
 * helper infrastructure
 ***********************************************************************/

const octetstring c_UICC_SELECT_MF := '00a40004023f00'O;
const octetstring c_SIM_SELECT_MF := 'a0a40004023f00'O;

/* Table 7 of ISO7816-3 */
type enumerated ISO7816_Fi {
	ISO7816_FI_372_4MHz	('0000'B),
	ISO7816_FI_372_5MHz	('0001'B),
	ISO7816_FI_558_6MHz	('0010'B),
	ISO7816_FI_744_8MHz	('0011'B),
	ISO7816_FI_1116_12MHz	('0100'B),
	ISO7816_FI_1488_16MHz	('0101'B),
	ISO7816_FI_1860_20MHz	('0110'B),

	ISO7816_FI_512_5MHz	('1001'B),
	ISO7816_FI_768_7MHz	('1010'B),
	ISO7816_FI_1024_10MHz	('1011'B),
	ISO7816_FI_1536_15MHz	('1100'B),
	ISO7816_FI_2048_20MHz	('1101'B)
};

/* Table 8 of ISO7816-3 */
type enumerated ISO7816_Di {
	ISO7816_DI_1		('0001'B),
	ISO7816_DI_2		('0010'B),
	ISO7816_DI_4		('0011'B),
	ISO7816_DI_8		('0100'B),
	ISO7816_DI_16		('0101'B),
	ISO7816_DI_32		('0110'B),
	ISO7816_DI_64		('0111'B),

	ISO7816_DI_12		('1000'B),
	ISO7816_DI_20		('1001'B)
}

private template (value) CCID_ProtocolData ts_ProtoDataT0(ISO7816_Fi fi, ISO7816_Di di,
							  uint8_t guard_time := 0,
							  uint8_t wait_int := 0) := {
	T0 := {
		Findex := enum2int(fi),
		Dindex := enum2int(di),

		bRFU := '000000'B,
		inv_convention := false,
		bRFU2 := '0'B,

		bGuardTimeT0 := guard_time,
		bWaitingIntegerT0 := wait_int,
		bClockStop := STOPPING_NOT_ALLOWED
	}
};

type function void_fn() runs on Slot_CT;

/* first function inside Slot_CT; wait for CCID_EVENT_UP + call testcase-specific function */
private function f_handler_init(void_fn fn, integer slot_nr) runs on Slot_CT {
	g_slot_nr := slot_nr;
	CCID.receive(CCID_Emulation_Event:{up_down:=CCID_EVENT_UP});
	g_Tguard.start;
	activate(as_Tguard());

	fn.apply();
}

/* start a single slot handler */
private function f_start_handler(void_fn fn, integer slot_nr) runs on Test_CT
{
	var Slot_CT vc;

	vc_SLOT[slot_nr] := Slot_CT.create("Slot" & int2str(slot_nr));
	connect(vc_SLOT[slot_nr]:CCID, vc_CCID:SLOT[slot_nr]);
	vc_SLOT[slot_nr].start(f_handler_init(fn, slot_nr));
}

private function f_wait_handlers_complete() runs on Test_CT {
	var integer i;

	for (i := 0; i < NR_SLOTS; i := i+1) {
		if (vc_SLOT[i] != null) {
			vc_SLOT[i].done;
		}
	}
	setverdict(pass);
}

private function f_start_and_wait() runs on Test_CT {
	/* start CCID_Emulation last, it will trigger all the per-slot components */
	var CCID_Emulation_Params cep := { usb_dev_match := mp_usb_dev_match };
        vc_CCID.start(CCID_Emulation.main(cep));
	f_wait_handlers_complete();
}

private function f_init() runs on Test_CT {
	var integer i;
	vc_CCID := CCID_Emulation_CT.create("CCID");
	map(vc_CCID:USB, system:USB);
	for (i := 0; i < NR_SLOTS; i := i+1) {
		vc_SLOT[i] := null;
	}
}



/***********************************************************************
 * Test behavior regarding valid situations
 ***********************************************************************/

/* request 100 times the slot status */
private function f_TC_getstatus() runs on Slot_CT
{
	var integer i;
	for (i := 0; i < 100; i := i+1) {
		CCID.send(ts_CCID_GetSlotStatus(g_slot_nr));
		/* it would be fun to simply send more requests here, but the CCID
		 * spec doesn't permit more than one unresponded command [per slot] */
		alt {
		[] CCID.receive(tr_CCID_SlotStatus(g_slot_nr));
		[] as_ccid_any();
		}
	}
	setverdict(pass);
}
testcase TC_get_status() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_getstatus), i);
	}

	f_start_and_wait();
}


private function f_TC_power_on() runs on Slot_CT
{
	f_ccid_power_on();
}
testcase TC_power_on() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_power_on), i);
	}

	f_start_and_wait();
}

private function f_TC_power_off() runs on Slot_CT
{
	f_ccid_power_on();
	f_ccid_power_off();
}
testcase TC_power_off() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_power_off), i);
	}

	f_start_and_wait();
}


/* repeat IccPowerOn on slot that's already active (next warm reset ATR) */
private function f_TC_power_on_warm() runs on Slot_CT
{
	var integer i;

	/* initial power on */
	f_ccid_power_on();

	/* additional power on */
	for (i := 0; i < 20; i := i+1) {
		f_ccid_power_on();
	}
}
testcase TC_power_on_warm() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_power_on_warm), i);
	}

	f_start_and_wait();
}

/* transfer 1000 APDUs by issuing SELECT MF */
private function f_TC_select_mf() runs on Slot_CT
{
	var integer i;
	f_ccid_power_on();
	f_ccid_set_par(ts_ProtoDataT0(ISO7816_FI_512_5MHz, ISO7816_DI_32));
	for (i := 0; i < 1000; i := i+1) {
		f_ccid_xfr(c_UICC_SELECT_MF, '??'O);
	}
}
testcase TC_select_mf() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_select_mf), i);
	}

	f_start_and_wait();
}

/* GetParametrs: verify contents */
private function f_TC_get_params() runs on Slot_CT
{
	var CCID_PDU par;
	f_ccid_power_on();
	par := f_ccid_get_par();
	log(par);
}
testcase TC_get_params() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_get_params), i);
	}
	f_start_and_wait();
}

/* SetParameters: verify change */
private function f_TC_set_params() runs on Slot_CT
{
	var CCID_PDU par;
	f_ccid_power_on();

	/* get current parameters */
	par := f_ccid_get_par();

	/* modify some of them */
	var CCID_ProtocolData pd := par.u.Parameters.abProtocolData;
	pd.T0.bGuardTimeT0 := 23;
	pd.T0.bWaitingIntegerT0 := 42;
	par := f_ccid_set_par(pd);

	/* check if modifications were applied */
	var template (present) CCID_ProtocolData tr_PD := {
		T0 := {
			Findex := ?,
			Dindex := ?,
			bRFU := ?,
			inv_convention := ?,
			bRFU2 := ?,
			bGuardTimeT0 := 23,
			bWaitingIntegerT0 := 42,
			bClockStop := ?
		}
	};
	if (match(par.u.Parameters.abProtocolData, tr_PD)) {
		setverdict(pass);
	} else {
		setverdict(fail, "SetParameters didn't change GuardTime/WaitingInteger");
	}
}
testcase TC_set_params() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_set_params), i);
	}
	f_start_and_wait();
}

/* ResetParameters: verify change */
private function f_TC_reset_params() runs on Slot_CT
{
	var CCID_PDU par;

	f_TC_set_params();
	par := f_ccid_reset_par();
	if (mp_quirk_resetpar_returns_slotsts) {
		par := f_ccid_get_par();
	}
	if (par.u.Parameters.abProtocolData.T0.bGuardTimeT0 == 23 or
	    par.u.Parameters.abProtocolData.T0.bWaitingIntegerT0 == 42) {
		setverdict(fail, "ResetParameters didn't reset properly");
	}
}
testcase TC_reset_params() runs on Test_CT
{
	var integer i;

	f_init();

	for (i := 0; i < mp_use_slot_count; i := i+1) {
		f_start_handler(refers(f_TC_reset_params), i);
	}
	f_start_and_wait();
}



/* TODO */
/* IccPowerOn: verify that CCID resets all parameters to default values */
/* IccPowerOn: verify that bPowerSelect has no effect in active state */
/* XfrBlock: length corner cases (Lc/Le max, ...) */
/* IccClock: verify clock has stopped/restarted */
/* Abort for command that already terminated */
/* Abort for command that's still processing */


/***********************************************************************
 * Test behavior regarding invalid situations
 ***********************************************************************/

/* message for invalid slot number (more than we have) */
private function f_TC_inval_slot() runs on Slot_CT {
	CCID.send(ts_CCID_GetSlotStatus(g_slot_nr));
	alt {
	[] CCID.receive(tr_CCID_SlotStatus(hdr_in := tr_CCID_HeaderIN_FAIL(CCID_ERR_SLOT_NOT_EXIST))) {
		setverdict(pass);
		}
	[] CCID.receive(tr_CCID_SlotStatus) {
		setverdict(fail, "Unexpected SlotStatus");
		mtc.stop;
		}
	[] as_ccid_any();
	}
}
testcase TC_inval_slot() runs on Test_CT {
	f_init();
	f_start_handler(refers(f_TC_inval_slot), 15);
	f_start_and_wait();
}

/* switch card off and then XfrBlock. Requires reader with IccPowerOff support */
private function f_TC_xfer_off() runs on Slot_CT {
	f_ccid_power_off();
	CCID.send(ts_CCID_XfrBlock(g_slot_nr, c_SIM_SELECT_MF, 0));
	alt {
	[] CCID.receive(tr_CCID_DataBlock(slot:=g_slot_nr, hdr_in:=tr_CCID_HeaderIN_FAIL)) {
		setverdict(pass);
		}
	[] CCID.receive(tr_CCID_DataBlock(slot:=g_slot_nr, hdr_in:=tr_CCID_HeaderIN_OK)) {
		setverdict(fail, "Expected XfrBlock to fail");
		mtc.stop;
		}
	[] as_ccid_any();
	}
}
testcase TC_xfer_off() runs on Test_CT {
	f_init();
	f_start_handler(refers(f_TC_xfer_off), 0);
	f_start_and_wait();
}


/* unsupported Mechanical */
private function f_TC_unsupp_mechanical() runs on Slot_CT {
	CCID.send(ts_CCID_Mechanical(g_slot_nr, CCID_MECH_FN_EJECT_CARD));
	alt {
	[] CCID.receive(tr_CCID_SlotStatus(hdr_in := tr_CCID_HeaderIN_FAIL(CCID_ERR_CMD_NOT_SUPPORTED))) {
		setverdict(pass);
		}
	[] as_ccid_any();
	}
}
testcase TC_unsupp_mechanical() runs on Test_CT {
	f_init();
	f_start_handler(refers(f_TC_unsupp_mechanical), 0);
	f_start_and_wait();
}

/* unsupported Secure */
private function f_TC_unsupp_secure() runs on Slot_CT {
	CCID.send(ts_CCID_Secure(g_slot_nr, 0, 0, ''O));
	alt {
	[] CCID.receive(tr_CCID_DataBlock(hdr_in := tr_CCID_HeaderIN_FAIL(CCID_ERR_CMD_NOT_SUPPORTED))) {
		setverdict(pass);
		}
	[] as_ccid_any();
	}
}
testcase TC_unsupp_secure() runs on Test_CT {
	f_init();
	f_start_handler(refers(f_TC_unsupp_secure), 0);
	f_start_and_wait();
}


/* TODO */
/* truncated message */
/* IccPowerOn with wrong voltage (> 0x04) */
/* XfrBlock on empty slot */
/* GetParameters on empty slot */
/* SetParameters for bProtocolNum > 0x01 */
/* SetParameters: invalid parameters */
/* set unsupported frequency */
/* set unsupported clock rate */
/* XfrBlock: bWI in T=0? */
/* XfrBlock: wLevelParameter not matching level? */
/* Abort for command that was not even submitted yet*/
/* dwMaxCCIDMessageLength */


control {
	/* valid transactions */
	execute( TC_get_status() );
	execute( TC_power_on() );
	execute( TC_power_on_warm() );
	if (mp_test_power_off) {
		execute( TC_power_off() );
	}
	execute( TC_select_mf() );
	execute( TC_get_params() );
	execute( TC_set_params() );
	execute( TC_reset_params() );

	/* error handling */
	execute( TC_inval_slot() );
	if (mp_test_power_off) {
		execute( TC_xfer_off() );
	}
	execute( TC_unsupp_mechanical() );
	execute( TC_unsupp_secure() );
}




}
