<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/14057">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><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;"><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: merged </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>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>