<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/16310">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">ccid: Many more CCID tests<br><br>Change-Id: Id046aff7c35b5ad3ab55fdf53a53e7637602d147<br>---<br>M ccid/CCID_Tests.ttcn<br>1 file changed, 404 insertions(+), 31 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/10/16310/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/ccid/CCID_Tests.ttcn b/ccid/CCID_Tests.ttcn</span><br><span>index cf615d4..f6816be 100644</span><br><span>--- a/ccid/CCID_Tests.ttcn</span><br><span>+++ b/ccid/CCID_Tests.ttcn</span><br><span>@@ -1,15 +1,27 @@</span><br><span> module CCID_Tests {</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* TTCN-3 tests for USB CCID (Chip Card Interface Device)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018-2019 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> import from General_Types all;</span><br><span> import from Osmocom_Types all;</span><br><span> import from Misc_Helpers all;</span><br><span> </span><br><span> import from USB_PortType all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from USB_Component all;</span><br><span> </span><br><span> import from CCID_Types all;</span><br><span> import from CCID_Templates all;</span><br><span> import from CCID_Emulation all;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+modulepar {</span><br><span style="color: hsl(120, 100%, 40%);">+ USB_Device_Match mp_usb_dev_match := { vid_pid := { vid := '1df0'H, pid := '6141'H } };</span><br><span style="color: hsl(120, 100%, 40%);">+ integer mp_use_slot_count := 8;</span><br><span style="color: hsl(120, 100%, 40%);">+ boolean mp_test_power_off := true;</span><br><span style="color: hsl(120, 100%, 40%);">+ boolean mp_quirk_resetpar_returns_slotsts := false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> /* global test component; manages CCID device */</span><br><span> type component Test_CT {</span><br><span> var CCID_Emulation_CT vc_CCID;</span><br><span>@@ -24,12 +36,16 @@</span><br><span> timer g_Tguard := 120.0;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-private const integer NR_SLOTS := 4;</span><br><span style="color: hsl(120, 100%, 40%);">+/* maximum number of slots we are supporting in the test suite */</span><br><span style="color: hsl(120, 100%, 40%);">+private const integer NR_SLOTS := 16;</span><br><span> </span><br><span> /***********************************************************************</span><br><span> * helper infrastructure</span><br><span> ***********************************************************************/</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+const octetstring c_UICC_SELECT_MF := '00a40004023f00'O;</span><br><span style="color: hsl(120, 100%, 40%);">+const octetstring c_SIM_SELECT_MF := 'a0a40004023f00'O;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> type function void_fn() runs on Slot_CT;</span><br><span> </span><br><span> /* altstep running on the per-slot test component */</span><br><span>@@ -39,6 +55,18 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+private altstep as_ccid_any() runs on Slot_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(CCID_PDU:?) -> value pdu {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Received unexpected CCID ", pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+ self.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Received unexpected non-CCID");</span><br><span style="color: hsl(120, 100%, 40%);">+ self.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* first function inside Slot_CT; wait for CCID_EVENT_UP + call testcase-specific function */</span><br><span> private function f_handler_init(void_fn fn, integer slot_nr) runs on Slot_CT {</span><br><span> g_slot_nr := slot_nr;</span><br><span>@@ -72,7 +100,8 @@</span><br><span> </span><br><span> private function f_start_and_wait() runs on Test_CT {</span><br><span> /* start CCID_Emulation last, it will trigger all the per-slot components */</span><br><span style="color: hsl(0, 100%, 40%);">- vc_CCID.start(CCID_Emulation.main());</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_Emulation_Params cep := { usb_dev_match := mp_usb_dev_match };</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_CCID.start(CCID_Emulation.main(cep));</span><br><span> f_wait_handlers_complete();</span><br><span> }</span><br><span> </span><br><span>@@ -85,37 +114,125 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-private function f_power_on(CCID_PowerSelect psel := CCID_PWRSEL_AUTO) runs on Slot_CT {</span><br><span style="color: hsl(0, 100%, 40%);">- CCID.send(ts_CCID_IccPowerOn(g_slot_nr, psel));</span><br><span style="color: hsl(0, 100%, 40%);">- CCID.receive(tr_CCID_DataBlock(g_slot_nr));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-private function f_xceive(octetstring tx, template octetstring rx) runs on Slot_CT return octetstring {</span><br><span style="color: hsl(120, 100%, 40%);">+/* transceive a CCID command (send 'tx' on OUT; expect 'rx' on IN) */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_xceive(template (value) CCID_PDU tx, template (present) CCID_PDU exp_rx)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span> var CCID_PDU pdu;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- CCID.send(ts_CCID_XfrBlock(g_slot_nr, tx, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+ tx.hdr.bSlot := g_slot_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+ exp_rx.hdr.bSlot := g_slot_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ CCID.send(tx);</span><br><span> alt {</span><br><span style="color: hsl(0, 100%, 40%);">- [] CCID.receive(tr_CCID_DataBlock(g_slot_nr, ?, rx)) -> value pdu {</span><br><span style="color: hsl(0, 100%, 40%);">- return pdu.u.DataBlock.abData;</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(exp_rx) -> value pdu {</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- [] CCID.receive(tr_CCID_DataBlock(g_slot_nr, ?, ?)) -> value pdu {</span><br><span style="color: hsl(0, 100%, 40%);">- setverdict(fail, "Received unexpected DataBlock ", pdu);</span><br><span style="color: hsl(0, 100%, 40%);">- self.stop;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- [] CCID.receive(CCID_PDU:?) -> value pdu {</span><br><span style="color: hsl(0, 100%, 40%);">- setverdict(fail, "Received unexpected CCID ", pdu);</span><br><span style="color: hsl(0, 100%, 40%);">- self.stop;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] as_ccid_any();</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- return ''O;</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private template (present) CCID_Header_IN tr_inact :=</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_HeaderIN_OK(icc_status := (CCID_ICC_STATUS_PRES_INACT, CCID_ICC_STATUS_NO_ICC));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private template (present) CCID_Header_IN tr_act :=</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_HeaderIN_OK(icc_status := CCID_ICC_STATUS_PRES_ACT);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send IccPowerOn on OUT; expect DataBlock in retunr */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_power_on(CCID_PowerSelect psel := CCID_PWRSEL_AUTO,</span><br><span style="color: hsl(120, 100%, 40%);">+ template (present) CCID_Header_IN hdr_in := tr_act)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_IccPowerOn(g_slot_nr, psel),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_DataBlock(g_slot_nr, hdr_in := hdr_in) );</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send IccPowerOn on OUT; expect SlotStatus in return */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_power_off(template (present) CCID_Header_IN hdr_in := tr_inact)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_IccPowerOff(g_slot_nr),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_SlotStatus(slot := g_slot_nr, hdr_in := hdr_in) );</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send IccClockCommand on OUT; expect SlotStatus in return */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_clock_cmd(CCID_ClockCommand cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_ClockCommand(g_slot_nr, cmd),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_SlotStatus(slot := g_slot_nr, hdr_in := hdr_in));</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send XfrBlock on OUT; expect DataBlock in return */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_xfr(octetstring tx, template octetstring rx) runs on Slot_CT return octetstring {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_XfrBlock(g_slot_nr, tx, 0),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_DataBlock(g_slot_nr, ?, ?, rx) );</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu.u.DataBlock.abData;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send SetParameters on OUT; expect Parameters on IN */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_set_par(template (value) CCID_ProtocolData par,</span><br><span style="color: hsl(120, 100%, 40%);">+ template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_SetParameters(g_slot_nr, par),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_Parameters(g_slot_nr, hdr_in := hdr_in));</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send GetParameters on OUT; expect Parameters on IN */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_get_par(template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_GetParameters(g_slot_nr),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_Parameters(g_slot_nr, hdr_in := hdr_in));</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send ResetParameters on OUT; expect Parameters on IN */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_reset_par(template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* [at least] Omnikey seems to have failed to follow the CCID spec here :/ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mp_quirk_resetpar_returns_slotsts) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_ResetParameters(g_slot_nr),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_SlotStatus(g_slot_nr, hdr_in := hdr_in));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_ResetParameters(g_slot_nr),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_Parameters(g_slot_nr, hdr_in := hdr_in));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send Escape on OUT; expect Escape on IN */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ccid_escape(template (value) octetstring data,</span><br><span style="color: hsl(120, 100%, 40%);">+ template (present) CCID_Header_IN hdr_in := tr_CCID_HeaderIN_OK)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on Slot_CT return CCID_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := f_ccid_xceive(ts_CCID_Escape(g_slot_nr, data),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_CCID_EscapeIN(g_slot_nr, hdr_in := hdr_in));</span><br><span style="color: hsl(120, 100%, 40%);">+ return pdu;</span><br><span> }</span><br><span> </span><br><span> </span><br><span> /***********************************************************************</span><br><span style="color: hsl(0, 100%, 40%);">- * actual test cases</span><br><span style="color: hsl(120, 100%, 40%);">+ * Test behavior regarding valid situations</span><br><span> ***********************************************************************/</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* request 100 times the slot status */</span><br><span> private function f_TC_getstatus() runs on Slot_CT</span><br><span> {</span><br><span>@@ -126,9 +243,7 @@</span><br><span> * spec doesn't permit more than one unresponded command [per slot] */</span><br><span> alt {</span><br><span> [] CCID.receive(tr_CCID_SlotStatus(g_slot_nr));</span><br><span style="color: hsl(0, 100%, 40%);">- [] CCID.receive {</span><br><span style="color: hsl(0, 100%, 40%);">- setverdict(fail, "Unexpected data from device");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] as_ccid_any();</span><br><span> }</span><br><span> }</span><br><span> setverdict(pass);</span><br><span>@@ -139,7 +254,7 @@</span><br><span> </span><br><span> f_init();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- for (i := 0; i < NR_SLOTS; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span> f_start_handler(refers(f_TC_getstatus), i);</span><br><span> }</span><br><span> </span><br><span>@@ -149,7 +264,7 @@</span><br><span> </span><br><span> private function f_TC_power_on() runs on Slot_CT</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- f_power_on();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_on();</span><br><span> }</span><br><span> testcase TC_power_on() runs on Test_CT</span><br><span> {</span><br><span>@@ -157,19 +272,65 @@</span><br><span> </span><br><span> f_init();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- for (i := 0; i < NR_SLOTS; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span> f_start_handler(refers(f_TC_power_on), i);</span><br><span> }</span><br><span> </span><br><span> f_start_and_wait();</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_power_off() runs on Slot_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_on();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_off();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_power_off() runs on Test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_power_off), i);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* repeat IccPowerOn on slot that's already active (next warm reset ATR) */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_power_on_warm() runs on Slot_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* initial power on */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_on();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* additional power on */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < 20; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_on();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_power_on_warm() runs on Test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_power_on_warm), i);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* transfer 1000 APDUs by issuing SELECT MF */</span><br><span> private function f_TC_select_mf() runs on Slot_CT</span><br><span> {</span><br><span> var integer i;</span><br><span style="color: hsl(0, 100%, 40%);">- f_power_on();</span><br><span style="color: hsl(0, 100%, 40%);">- for (i := 0; i < 10000; i := i+1) {</span><br><span style="color: hsl(0, 100%, 40%);">- f_xceive('00a40004023f00'O, ?);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_on();</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < 1000; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_xfr(c_UICC_SELECT_MF, ?);</span><br><span> }</span><br><span> }</span><br><span> testcase TC_select_mf() runs on Test_CT</span><br><span>@@ -178,19 +339,231 @@</span><br><span> </span><br><span> f_init();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- for (i := 0; i < NR_SLOTS; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span> f_start_handler(refers(f_TC_select_mf), i);</span><br><span> }</span><br><span> </span><br><span> f_start_and_wait();</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* GetParametrs: verify contents */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_get_params() runs on Slot_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU par;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_on();</span><br><span style="color: hsl(120, 100%, 40%);">+ par := f_ccid_get_par();</span><br><span style="color: hsl(120, 100%, 40%);">+ log(par);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_get_params() runs on Test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_get_params), i);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* SetParameters: verify change */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_set_params() runs on Slot_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU par;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_on();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* get current parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+ par := f_ccid_get_par();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* modify some of them */</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_ProtocolData pd := par.u.Parameters.abProtocolData;</span><br><span style="color: hsl(120, 100%, 40%);">+ pd.T0.bGuardTimeT0 := 23;</span><br><span style="color: hsl(120, 100%, 40%);">+ pd.T0.bWaitingIntegerT0 := 42;</span><br><span style="color: hsl(120, 100%, 40%);">+ par := f_ccid_set_par(pd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* check if modifications were applied */</span><br><span style="color: hsl(120, 100%, 40%);">+ var template (present) CCID_ProtocolData tr_PD := {</span><br><span style="color: hsl(120, 100%, 40%);">+ T0 := {</span><br><span style="color: hsl(120, 100%, 40%);">+ Findex := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ Dindex := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ bRFU := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ inv_convention := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ bRFU2 := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ bGuardTimeT0 := 23,</span><br><span style="color: hsl(120, 100%, 40%);">+ bWaitingIntegerT0 := 42,</span><br><span style="color: hsl(120, 100%, 40%);">+ bClockStop := ?</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match(par.u.Parameters.abProtocolData, tr_PD)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "SetParameters didn't change GuardTime/WaitingInteger");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_set_params() runs on Test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_set_params), i);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* ResetParameters: verify change */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_reset_params() runs on Slot_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var CCID_PDU par;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_TC_set_params();</span><br><span style="color: hsl(120, 100%, 40%);">+ par := f_ccid_reset_par();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mp_quirk_resetpar_returns_slotsts) {</span><br><span style="color: hsl(120, 100%, 40%);">+ par := f_ccid_get_par();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (par.u.Parameters.abProtocolData.T0.bGuardTimeT0 == 23 or</span><br><span style="color: hsl(120, 100%, 40%);">+ par.u.Parameters.abProtocolData.T0.bWaitingIntegerT0 == 42) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "ResetParameters didn't reset properly");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_reset_params() runs on Test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < mp_use_slot_count; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_reset_params), i);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* TODO */</span><br><span style="color: hsl(120, 100%, 40%);">+/* IccPowerOn: verify that CCID resets all parameters to default values */</span><br><span style="color: hsl(120, 100%, 40%);">+/* IccPowerOn: verify that bPowerSelect has no effect in active state */</span><br><span style="color: hsl(120, 100%, 40%);">+/* XfrBlock: length corner cases (Lc/Le max, ...) */</span><br><span style="color: hsl(120, 100%, 40%);">+/* IccClock: verify clock has stopped/restarted */</span><br><span style="color: hsl(120, 100%, 40%);">+/* Abort for command that already terminated */</span><br><span style="color: hsl(120, 100%, 40%);">+/* Abort for command that's still processing */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * Test behavior regarding invalid situations</span><br><span style="color: hsl(120, 100%, 40%);">+ ***********************************************************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* message for invalid slot number (more than we have) */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_inval_slot() runs on Slot_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ CCID.send(ts_CCID_GetSlotStatus(g_slot_nr));</span><br><span style="color: hsl(120, 100%, 40%);">+ alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(tr_CCID_SlotStatus(hdr_in := tr_CCID_HeaderIN_FAIL(CCID_ERR_SLOT_NOT_EXIST))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(tr_CCID_SlotStatus) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Unexpected SlotStatus");</span><br><span style="color: hsl(120, 100%, 40%);">+ mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] as_ccid_any();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_inval_slot() runs on Test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_inval_slot), 15);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* switch card off and then XfrBlock. Requires reader with IccPowerOff support */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_xfer_off() runs on Slot_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ccid_power_off();</span><br><span style="color: hsl(120, 100%, 40%);">+ CCID.send(ts_CCID_XfrBlock(g_slot_nr, c_SIM_SELECT_MF, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+ alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(tr_CCID_DataBlock(slot:=g_slot_nr, hdr_in:=tr_CCID_HeaderIN_FAIL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(tr_CCID_DataBlock(slot:=g_slot_nr, hdr_in:=tr_CCID_HeaderIN_OK)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Expected XfrBlock to fail");</span><br><span style="color: hsl(120, 100%, 40%);">+ mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] as_ccid_any();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_xfer_off() runs on Test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_xfer_off), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* unsupported Mechanical */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_unsupp_mechanical() runs on Slot_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ CCID.send(ts_CCID_Mechanical(g_slot_nr, CCID_MECH_FN_EJECT_CARD));</span><br><span style="color: hsl(120, 100%, 40%);">+ alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(tr_CCID_SlotStatus(hdr_in := tr_CCID_HeaderIN_FAIL(CCID_ERR_CMD_NOT_SUPPORTED))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] as_ccid_any();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_unsupp_mechanical() runs on Test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_unsupp_mechanical), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* unsupported Secure */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_unsupp_secure() runs on Slot_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ CCID.send(ts_CCID_Secure(g_slot_nr, 0, 0, ''O));</span><br><span style="color: hsl(120, 100%, 40%);">+ alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] CCID.receive(tr_CCID_DataBlock(hdr_in := tr_CCID_HeaderIN_FAIL(CCID_ERR_CMD_NOT_SUPPORTED))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] as_ccid_any();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_unsupp_secure() runs on Test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_handler(refers(f_TC_unsupp_secure), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_start_and_wait();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* TODO */</span><br><span style="color: hsl(120, 100%, 40%);">+/* truncated message */</span><br><span style="color: hsl(120, 100%, 40%);">+/* IccPowerOn with wrong voltage (> 0x04) */</span><br><span style="color: hsl(120, 100%, 40%);">+/* XfrBlock on empty slot */</span><br><span style="color: hsl(120, 100%, 40%);">+/* GetParameters on empty slot */</span><br><span style="color: hsl(120, 100%, 40%);">+/* SetParameters for bProtocolNum > 0x01 */</span><br><span style="color: hsl(120, 100%, 40%);">+/* SetParameters: invalid parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+/* set unsupported frequency */</span><br><span style="color: hsl(120, 100%, 40%);">+/* set unsupported clock rate */</span><br><span style="color: hsl(120, 100%, 40%);">+/* XfrBlock: bWI in T=0? */</span><br><span style="color: hsl(120, 100%, 40%);">+/* XfrBlock: wLevelParameter not matching level? */</span><br><span style="color: hsl(120, 100%, 40%);">+/* Abort for command that was not even submitted yet*/</span><br><span style="color: hsl(120, 100%, 40%);">+/* dwMaxCCIDMessageLength */</span><br><span> </span><br><span> </span><br><span> control {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* valid transactions */</span><br><span> execute( TC_get_status() );</span><br><span> execute( TC_power_on() );</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_power_on_warm() );</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mp_test_power_off) {</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_power_off() );</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> execute( TC_select_mf() );</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_get_params() );</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_set_params() );</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_reset_params() );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* error handling */</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_inval_slot() );</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mp_test_power_off) {</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_xfer_off() );</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_unsupp_mechanical() );</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_unsupp_secure() );</span><br><span> }</span><br><span> </span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/16310">change 16310</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/16310"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-ttcn3-hacks </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Id046aff7c35b5ad3ab55fdf53a53e7637602d147 </div>
<div style="display:none"> Gerrit-Change-Number: 16310 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>