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];
};

/* per-slot test component; manages one slot */
type component Slot_CT {
	var uint8_t g_slot_nr;
	port CCID_SLOT_PT CCID;
	timer g_Tguard := 120.0;
};

/* 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;

/* altstep running on the per-slot test component */
private altstep as_Tguard() runs on Slot_CT {
	[] g_Tguard.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Tguard timeout");
		}
}

private altstep as_ccid_any() runs on Slot_CT {
	var CCID_PDU pdu;
	[] CCID.receive(CCID_PDU:?) -> value pdu {
		setverdict(fail, "Received unexpected CCID ", pdu);
		self.stop;
		}
	[] CCID.receive {
		setverdict(fail, "Received unexpected non-CCID");
		self.stop;
		}
}

/* 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;
	}
}


/* transceive a CCID command (send 'tx' on OUT; expect 'rx' on IN) */
private function f_ccid_xceive(template (value) CCID_PDU tx, template (present) CCID_PDU exp_rx)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	tx.hdr.bSlot := g_slot_nr;
	exp_rx.hdr.bSlot := g_slot_nr;

	CCID.send(tx);
	alt {
	[] CCID.receive(exp_rx) -> value pdu {
		return pdu;
		}
	[] as_ccid_any();
	}
	return pdu;
}

private template (present) CCID_Header_IN tr_inact :=
	tr_CCID_HeaderIN_OK(icc_status := (CCID_ICC_STATUS_PRES_INACT, CCID_ICC_STATUS_NO_ICC));

private template (present) CCID_Header_IN tr_act :=
	tr_CCID_HeaderIN_OK(icc_status := CCID_ICC_STATUS_PRES_ACT);

/* Send IccPowerOn on OUT; expect DataBlock in retunr */
private function f_ccid_power_on(CCID_PowerSelect psel := CCID_PWRSEL_AUTO,
				 template (present) CCID_Header_IN hdr_in := tr_act)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	pdu := f_ccid_xceive(ts_CCID_IccPowerOn(g_slot_nr, psel),
			     tr_CCID_DataBlock(g_slot_nr, hdr_in := hdr_in) );
	return pdu;
}

/* Send IccPowerOn on OUT; expect SlotStatus in return */
private function f_ccid_power_off(template (present) CCID_Header_IN hdr_in := tr_inact)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	pdu := f_ccid_xceive(ts_CCID_IccPowerOff(g_slot_nr),
			     tr_CCID_SlotStatus(slot := g_slot_nr, hdr_in := hdr_in) );
	return pdu;
}

/* Send IccClockCommand on OUT; expect SlotStatus in return */
private function f_ccid_clock_cmd(CCID_ClockCommand cmd,
				  template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	pdu := f_ccid_xceive(ts_CCID_ClockCommand(g_slot_nr, cmd),
			     tr_CCID_SlotStatus(slot := g_slot_nr, hdr_in := hdr_in));
	return pdu;
}

/* Send XfrBlock on OUT; expect DataBlock in return */
private function f_ccid_xfr(octetstring tx, template octetstring rx) runs on Slot_CT return octetstring {
	var CCID_PDU pdu;

	pdu := f_ccid_xceive(ts_CCID_XfrBlock(g_slot_nr, tx, 0),
			     tr_CCID_DataBlock(g_slot_nr, ?, ?, rx) );
	return pdu.u.DataBlock.abData;
}

/* Send SetParameters on OUT; expect Parameters on IN */
private function f_ccid_set_par(template (value) CCID_ProtocolData par,
				template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	pdu := f_ccid_xceive(ts_CCID_SetParameters(g_slot_nr, par),
			     tr_CCID_Parameters(g_slot_nr, hdr_in := hdr_in));
	return pdu;
}

/* Send GetParameters on OUT; expect Parameters on IN */
private function f_ccid_get_par(template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	pdu := f_ccid_xceive(ts_CCID_GetParameters(g_slot_nr),
			     tr_CCID_Parameters(g_slot_nr, hdr_in := hdr_in));
	return pdu;
}

/* Send ResetParameters on OUT; expect Parameters on IN */
private function f_ccid_reset_par(template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	/* [at least] Omnikey seems to have failed to follow the CCID spec here :/ */
	if (mp_quirk_resetpar_returns_slotsts) {
		pdu := f_ccid_xceive(ts_CCID_ResetParameters(g_slot_nr),
				     tr_CCID_SlotStatus(g_slot_nr, hdr_in := hdr_in));
	} else {
		pdu := f_ccid_xceive(ts_CCID_ResetParameters(g_slot_nr),
				     tr_CCID_Parameters(g_slot_nr, hdr_in := hdr_in));
	}
	return pdu;
}

/* Send Escape on OUT; expect Escape on IN */
private function f_ccid_escape(template (value) octetstring data,
				template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)
runs on Slot_CT return CCID_PDU {
	var CCID_PDU pdu;

	pdu := f_ccid_xceive(ts_CCID_Escape(g_slot_nr, data),
			     tr_CCID_EscapeIN(g_slot_nr, hdr_in := hdr_in));
	return pdu;
}


/***********************************************************************
 * 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() );
}




}
