<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>