<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/14057">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">ccid: Implement encode/decode of ProtocolParameters<br><br>Change-Id: Id6c436916a54b98a11809a58e9154e3e9b627885<br>---<br>M ccid/ccid_device.c<br>M ccid/ccid_proto.h<br>2 files changed, 175 insertions(+), 20 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware refs/changes/57/14057/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/ccid/ccid_device.c b/ccid/ccid_device.c</span><br><span>index 340ff60..02d1599 100644</span><br><span>--- a/ccid/ccid_device.c</span><br><span>+++ b/ccid/ccid_device.c</span><br><span>@@ -11,6 +11,28 @@</span><br><span> </span><br><span> #define NR_SLOTS 8</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct ccid_pars_decoded {</span><br><span style="color: hsl(120, 100%, 40%);">+     /* global for T0/T1 */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t fi;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t di;</span><br><span style="color: hsl(120, 100%, 40%);">+   enum ccid_clock_stop clock_stop;</span><br><span style="color: hsl(120, 100%, 40%);">+      bool inverse_convention;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              uint8_t guard_time_etu;</span><br><span style="color: hsl(120, 100%, 40%);">+               uint8_t waiting_integer;</span><br><span style="color: hsl(120, 100%, 40%);">+      } t0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              enum ccid_t1_csum_type csum_type;</span><br><span style="color: hsl(120, 100%, 40%);">+             uint8_t guard_time_t1;</span><br><span style="color: hsl(120, 100%, 40%);">+                uint8_t bwi;</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t cwi;</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t ifsc;</span><br><span style="color: hsl(120, 100%, 40%);">+         uint8_t nad;</span><br><span style="color: hsl(120, 100%, 40%);">+  } t1;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ccid_slot {</span><br><span>    struct ccid_instance *ci;</span><br><span>    uint8_t slot_nr;</span><br><span>@@ -18,8 +40,100 @@</span><br><span>       bool icc_powered;</span><br><span>    bool icc_in_reset;</span><br><span>   bool cmd_busy;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ccid_pars_decoded pars;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* decode on-the-wire T0 parameters into their parsed form */</span><br><span style="color: hsl(120, 100%, 40%);">+static int decode_ccid_pars_t0(struct ccid_pars_decoded *out, const struct ccid_proto_data_t0 *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        /* input validation: only 0x00 and 0x02 permitted for bmTCCKST0 */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (in->bmTCCKST0 & 0xFD)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -11;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* input validation: only 0x00 to 0x03 permitted for bClockSTop */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (in->bClockStop & 0xFC)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -14;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ out->fi = in->bmFindexDindex >> 4;</span><br><span style="color: hsl(120, 100%, 40%);">+        out->di = in->bmFindexDindex & 0xF;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (in->bmTCCKST0 & 2)</span><br><span style="color: hsl(120, 100%, 40%);">+         out->inverse_convention = true;</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          out->inverse_convention = false;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (in->bGuardTimeT0 == 0xff)</span><br><span style="color: hsl(120, 100%, 40%);">+              out->t0.guard_time_etu = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        else</span><br><span style="color: hsl(120, 100%, 40%);">+          out->t0.guard_time_etu = in->bGuardTimeT0;</span><br><span style="color: hsl(120, 100%, 40%);">+      out->t0.waiting_integer = in->bWaitingIntegerT0;</span><br><span style="color: hsl(120, 100%, 40%);">+        out->clock_stop = in->bClockStop & 0x03;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return 0;</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%);">+/* encode T0 parameters from parsed form into on-the-wire encoding */</span><br><span style="color: hsl(120, 100%, 40%);">+static void encode_ccid_pars_t0(struct ccid_proto_data_t0 *out, const struct ccid_pars_decoded *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ out->bmFindexDindex = ((in->fi << 4) & 0xF0) | (in->di & 0x0F);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (in->inverse_convention)</span><br><span style="color: hsl(120, 100%, 40%);">+                out->bmTCCKST0 = 0x02;</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          out->bmTCCKST0 = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+     out->bGuardTimeT0 = in->t0.guard_time_etu;</span><br><span style="color: hsl(120, 100%, 40%);">+      out->bWaitingIntegerT0 = in->t0.waiting_integer;</span><br><span style="color: hsl(120, 100%, 40%);">+        out->bClockStop = in->clock_stop & 0x03;</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%);">+/* decode on-the-wire T1 parameters into their parsed form */</span><br><span style="color: hsl(120, 100%, 40%);">+static int decode_ccid_pars_t1(struct ccid_pars_decoded *out, const struct ccid_proto_data_t1 *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* input validation: only some values permitted for bmTCCKST0 */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (in->bmTCCKST1 & 0xE8)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -11;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* input validation: only 0x00 to 0x9F permitted for bmWaitingIntegersT1 */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (in->bWaitingIntegersT1 > 0x9F)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -13;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* input validation: only 0x00 to 0x03 permitted for bClockSTop */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (in->bClockStop & 0xFC)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -14;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* input validation: only 0x00 to 0xFE permitted for bIFSC */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (in->bIFSC > 0xFE)</span><br><span style="color: hsl(120, 100%, 40%);">+           return -15;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ out->fi = in->bmFindexDindex >> 4;</span><br><span style="color: hsl(120, 100%, 40%);">+        out->di = in->bmFindexDindex & 0xF;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (in->bmTCCKST1 & 1)</span><br><span style="color: hsl(120, 100%, 40%);">+         out->t1.csum_type = CCID_CSUM_TYPE_CRC;</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          out->t1.csum_type = CCID_CSUM_TYPE_LRC;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (in->bmTCCKST1 & 2)</span><br><span style="color: hsl(120, 100%, 40%);">+         out->inverse_convention = true;</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          out->inverse_convention = false;</span><br><span style="color: hsl(120, 100%, 40%);">+   out->t1.guard_time_t1 = in->bGuardTimeT1;</span><br><span style="color: hsl(120, 100%, 40%);">+       out->t1.bwi = in->bWaitingIntegersT1 >> 4;</span><br><span style="color: hsl(120, 100%, 40%);">+        out->t1.cwi = in->bWaitingIntegersT1 & 0xF;</span><br><span style="color: hsl(120, 100%, 40%);">+ out->clock_stop = in->bClockStop & 0x03;</span><br><span style="color: hsl(120, 100%, 40%);">+    out->t1.ifsc = in->bIFSC;</span><br><span style="color: hsl(120, 100%, 40%);">+       out->t1.nad = in->bNadValue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return 0;</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%);">+/* encode T1 parameters from parsed form into on-the-wire encoding */</span><br><span style="color: hsl(120, 100%, 40%);">+static void encode_ccid_pars_t1(struct ccid_proto_data_t1 *out, const struct ccid_pars_decoded *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ out->bmFindexDindex = ((in->fi << 4) & 0xF0) | (in->di & 0x0F);</span><br><span style="color: hsl(120, 100%, 40%);">+        out->bmTCCKST1 = 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (in->t1.csum_type == CCID_CSUM_TYPE_CRC)</span><br><span style="color: hsl(120, 100%, 40%);">+                out->bmTCCKST1 |= 0x01;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (in->inverse_convention)</span><br><span style="color: hsl(120, 100%, 40%);">+                out->bmTCCKST1 |= 0x02;</span><br><span style="color: hsl(120, 100%, 40%);">+    out->bGuardTimeT1 = in->t1.guard_time_t1;</span><br><span style="color: hsl(120, 100%, 40%);">+       out->bWaitingIntegersT1 = ((in->t1.bwi << 4) & 0xF0) | (in->t1.cwi & 0x0F);</span><br><span style="color: hsl(120, 100%, 40%);">+    out->bClockStop = in->clock_stop & 0x03;</span><br><span style="color: hsl(120, 100%, 40%);">+    out->bIFSC = in->t1.ifsc;</span><br><span style="color: hsl(120, 100%, 40%);">+       out->bNadValue = in->t1.nad;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ccid_ops {</span><br><span>         int (*send_in)(struct ccid_instance *ci, struct msgb *msg);</span><br><span> };</span><br><span>@@ -154,48 +268,46 @@</span><br><span> /* Section 6.2.3 */</span><br><span> static struct msgb *ccid_gen_parameters_t0_nr(uint8_t slot_nr, uint8_t icc_status,</span><br><span>                                             uint8_t seq, uint8_t cmd_sts, enum ccid_error_code err,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         const struct ccid_proto_data_t0 *t0)</span><br><span style="color: hsl(120, 100%, 40%);">+                                          const struct ccid_pars_decoded *dec_par)</span><br><span> {</span><br><span>  struct msgb *msg = ccid_msgb_alloc();</span><br><span>        struct ccid_rdr_to_pc_parameters *par =</span><br><span style="color: hsl(0, 100%, 40%);">-         (struct ccid_rdr_to_pc_parameters *) msgb_put(msg, sizeof(par->hdr)+sizeof(*t0));</span><br><span style="color: hsl(120, 100%, 40%);">+          (struct ccid_rdr_to_pc_parameters *) msgb_put(msg, sizeof(par->hdr)+sizeof(par->abProtocolData.t0));</span><br><span>   uint8_t sts = (cmd_sts & CCID_CMD_STATUS_MASK) | icc_status;</span><br><span> </span><br><span>         SET_HDR_IN(par, RDR_to_PC_Parameters, slot_nr, seq, sts, err);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (t0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               osmo_store32le(sizeof(*t0), &par->hdr.hdr.dwLength);</span><br><span style="color: hsl(0, 100%, 40%);">-             par->abProtocolData.t0 = *t0;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (dec_par) {</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_store32le(sizeof(par->abProtocolData.t0), &par->hdr.hdr.dwLength);</span><br><span style="color: hsl(120, 100%, 40%);">+             encode_ccid_pars_t0(&par->abProtocolData.t0, dec_par);</span><br><span>        }</span><br><span>    return msg;</span><br><span> }</span><br><span> static struct msgb *ccid_gen_parameters_t0(struct ccid_slot *cs, uint8_t seq, uint8_t cmd_sts,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         enum ccid_error_code err,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       const struct ccid_proto_data_t0 *t0)</span><br><span style="color: hsl(120, 100%, 40%);">+                                          enum ccid_error_code err)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       return ccid_gen_parameters_t0_nr(cs->slot_nr, get_icc_status(cs), seq, cmd_sts, err, t0);</span><br><span style="color: hsl(120, 100%, 40%);">+  return ccid_gen_parameters_t0_nr(cs->slot_nr, get_icc_status(cs), seq, cmd_sts, err, &cs->pars);</span><br><span> }</span><br><span> </span><br><span> static struct msgb *ccid_gen_parameters_t1_nr(uint8_t slot_nr, uint8_t icc_status,</span><br><span>                                          uint8_t seq, uint8_t cmd_sts, enum ccid_error_code err,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         const struct ccid_proto_data_t1 *t1)</span><br><span style="color: hsl(120, 100%, 40%);">+                                          const struct ccid_pars_decoded *dec_par)</span><br><span> {</span><br><span>  struct msgb *msg = ccid_msgb_alloc();</span><br><span>        struct ccid_rdr_to_pc_parameters *par =</span><br><span style="color: hsl(0, 100%, 40%);">-         (struct ccid_rdr_to_pc_parameters *) msgb_put(msg, sizeof(par->hdr)+sizeof(*t1));</span><br><span style="color: hsl(120, 100%, 40%);">+          (struct ccid_rdr_to_pc_parameters *) msgb_put(msg, sizeof(par->hdr)+sizeof(par->abProtocolData.t1));</span><br><span>   uint8_t sts = (cmd_sts & CCID_CMD_STATUS_MASK) | icc_status;</span><br><span> </span><br><span>         SET_HDR_IN(par, RDR_to_PC_Parameters, slot_nr, seq, sts, err);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (t1) {</span><br><span style="color: hsl(0, 100%, 40%);">-               osmo_store32le(sizeof(*t1), &par->hdr.hdr.dwLength);</span><br><span style="color: hsl(0, 100%, 40%);">-             par->abProtocolData.t1 = *t1;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (dec_par) {</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_store32le(sizeof(par->abProtocolData.t1), &par->hdr.hdr.dwLength);</span><br><span style="color: hsl(120, 100%, 40%);">+             encode_ccid_pars_t1(&par->abProtocolData.t1, dec_par);</span><br><span>        }</span><br><span>    return msg;</span><br><span> }</span><br><span> static struct msgb *ccid_gen_parameters_t1(struct ccid_slot *cs, uint8_t seq, uint8_t cmd_sts,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         enum ccid_error_code err,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       const struct ccid_proto_data_t1 *t1)</span><br><span style="color: hsl(120, 100%, 40%);">+                                          enum ccid_error_code err)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       return ccid_gen_parameters_t1_nr(cs->slot_nr, get_icc_status(cs), seq, cmd_sts, err, t1);</span><br><span style="color: hsl(120, 100%, 40%);">+  return ccid_gen_parameters_t1_nr(cs->slot_nr, get_icc_status(cs), seq, cmd_sts, err, &cs->pars);</span><br><span> }</span><br><span> </span><br><span> </span><br><span>@@ -372,7 +484,8 @@</span><br><span>        uint8_t seq = u->get_parameters.hdr.bSeq;</span><br><span>         struct msgb *resp;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /* FIXME */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* FIXME: T=1 */</span><br><span style="color: hsl(120, 100%, 40%);">+      resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_OK, 0);</span><br><span>       return ccid_slot_send_unbusy(cs, resp);</span><br><span> }</span><br><span> </span><br><span>@@ -384,7 +497,9 @@</span><br><span>       uint8_t seq = u->reset_parameters.hdr.bSeq;</span><br><span>       struct msgb *resp;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /* FIXME */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* FIXME: copy default parameters from somewhere */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* FIXME: T=1 */</span><br><span style="color: hsl(120, 100%, 40%);">+      resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_OK, 0);</span><br><span>       return ccid_slot_send_unbusy(cs, resp);</span><br><span> }</span><br><span> </span><br><span>@@ -392,11 +507,34 @@</span><br><span> static int ccid_handle_set_parameters(struct ccid_slot *cs, struct msgb *msg)</span><br><span> {</span><br><span>       const union ccid_pc_to_rdr *u = msgb_ccid_out(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct ccid_pc_to_rdr_set_parameters *spar = &u->set_parameters;</span><br><span>        const struct ccid_header *ch = (const struct ccid_header *) u;</span><br><span>       uint8_t seq = u->set_parameters.hdr.bSeq;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct ccid_pars_decoded pars_dec;</span><br><span>   struct msgb *resp;</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     /* FIXME */</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (spar->bProtocolNum) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case CCID_PROTOCOL_NUM_T0:</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = decode_ccid_pars_t0(&pars_dec, &spar->abProtocolData.t0);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                        resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_FAILED, -rc);</span><br><span style="color: hsl(120, 100%, 40%);">+          /* FIXME: validate parameters; abort if they are not supported */</span><br><span style="color: hsl(120, 100%, 40%);">+             cs->pars = pars_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+               resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_OK, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CCID_PROTOCOL_NUM_T1:</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = decode_ccid_pars_t1(&pars_dec, &spar->abProtocolData.t1);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                        resp = ccid_gen_parameters_t1(cs, seq, CCID_CMD_STATUS_FAILED, -rc);</span><br><span style="color: hsl(120, 100%, 40%);">+          /* FIXME: validate parameters; abort if they are not supported */</span><br><span style="color: hsl(120, 100%, 40%);">+             cs->pars = pars_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+               resp = ccid_gen_parameters_t1(cs, seq, CCID_CMD_STATUS_OK, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_FAILED, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span>    return ccid_slot_send_unbusy(cs, resp);</span><br><span> }</span><br><span> </span><br><span>diff --git a/ccid/ccid_proto.h b/ccid/ccid_proto.h</span><br><span>index fa0ead1..92878dc 100644</span><br><span>--- a/ccid/ccid_proto.h</span><br><span>+++ b/ccid/ccid_proto.h</span><br><span>@@ -132,6 +132,23 @@</span><br><span> /* Response: RDR_to_PC_Parameters */</span><br><span> </span><br><span> /* Section 6.1.7 */</span><br><span style="color: hsl(120, 100%, 40%);">+enum ccid_protocol_num {</span><br><span style="color: hsl(120, 100%, 40%);">+ CCID_PROTOCOL_NUM_T0    = 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+       CCID_PROTOCOL_NUM_T1    = 0x01,</span><br><span style="color: hsl(120, 100%, 40%);">+       CCID_PROTOCOL_NUM_2WIRE = 0x80,</span><br><span style="color: hsl(120, 100%, 40%);">+       CCID_PROTOCOL_NUM_3WIRE = 0x81,</span><br><span style="color: hsl(120, 100%, 40%);">+       CCID_PROTOCOL_NUM_I2C   = 0x82,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+enum ccid_clock_stop {</span><br><span style="color: hsl(120, 100%, 40%);">+   CCID_CLOCK_STOP_NOTALLOWED      = 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+       CCID_CLOCK_STOP_LOW             = 0x01,</span><br><span style="color: hsl(120, 100%, 40%);">+       CCID_CLOCK_STOP_HIGH            = 0x02,</span><br><span style="color: hsl(120, 100%, 40%);">+       CCID_CLOCK_STOP_EITHER          = 0x03,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+enum ccid_t1_csum_type {</span><br><span style="color: hsl(120, 100%, 40%);">+ CCID_CSUM_TYPE_LRC      = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  CCID_CSUM_TYPE_CRC      = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span> struct ccid_proto_data_t0 {</span><br><span>      uint8_t bmFindexDindex;</span><br><span>      uint8_t bmTCCKST0;</span><br><span>@@ -145,7 +162,7 @@</span><br><span>     uint8_t bGuardTimeT1;</span><br><span>        uint8_t bWaitingIntegersT1;</span><br><span>  uint8_t bClockStop;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t bFSC;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t bIFSC;</span><br><span>       uint8_t bNadValue;</span><br><span> } __attribute__ ((packed));</span><br><span> struct ccid_pc_to_rdr_set_parameters {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/14057">change 14057</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/14057"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-ccid-firmware </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Id6c436916a54b98a11809a58e9154e3e9b627885 </div>
<div style="display:none"> Gerrit-Change-Number: 14057 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>