1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef __USB_DEVICE_CCID_H__
10 #define __USB_DEVICE_CCID_H__
11 
12 /*!
13  * @addtogroup usb_device_ccid_drv
14  * @{
15  */
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*!
22  * @name USB CCID device class configuration
23  * @{
24  */
25 
26 /*! @brief MAX slot number of the CCID device. */
27 #define USB_DEVICE_CONFIG_CCID_SLOT_MAX (1U)
28 /*! @brief MAX transfer entity number of the CCID device. */
29 #define USB_DEVICE_CONFIG_CCID_TRANSFER_COUNT (4U)
30 /*! @brief MAX maximum message length of the CCID device. */
31 #define USB_DEVICE_CONFIG_CCID_MAX_MESSAGE_LENGTH (271U)
32 
33 /*! @}*/
34 
35 /*! @brief CCID device class code */
36 #define USB_DEVICE_CCID_CLASS_CODE (0x0BU)
37 /*! @brief CCID device subclass code */
38 #define USB_DEVICE_CCID_SUBCLASS_CODE (0x00U)
39 /*! @brief CCID device protocol code */
40 #define USB_DEVICE_CCID_PROTOCOL_CODE (0x00U)
41 
42 /*!
43  * @name USB CCID device class descriptor
44  * @{
45  */
46 
47 /* CCID device class-specific descriptor length */
48 #define USB_DEVICE_CCID_DESCRIPTOR_LENGTH (0x36U)
49 /* CCID device class-specific descriptor type */
50 #define USB_DEVICE_CCID_DESCRIPTOR_TYPE (0x21U)
51 
52 /* The voltage support in CCID device class-specific descriptor */
53 #define USB_DEVICE_CCID_DESCRIPTOR_VOLTAGE_SUPPORT_BM_5V (0x01U)
54 #define USB_DEVICE_CCID_DESCRIPTOR_VOLTAGE_SUPPORT_BM_3V (0x02U)
55 #define USB_DEVICE_CCID_DESCRIPTOR_VOLTAGE_SUPPORT_BM_1V8 (0x04U)
56 
57 /* The protocol in CCID device class-specific descriptor */
58 #define USB_DEVICE_CCID_DESCRIPTOR_PROTOCOLS_BM_T0 (0x00000001U)
59 #define USB_DEVICE_CCID_DESCRIPTOR_PROTOCOLS_BM_T1 (0x00000002U)
60 
61 /* The mechanical in CCID device class-specific descriptor */
62 #define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_NO (0x00000000U)
63 #define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_ACCEPT (0x00000001U)
64 #define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_EJECTION (0x00000002U)
65 #define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_CAPTURE (0x00000004U)
66 #define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_LOCK_UNLCOK (0x00000008U)
67 
68 /* The features in CCID device class-specific descriptor */
69 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_NO (0x00000000U)
70 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_CONFIG_BASED_ON_ATR (0x00000002U)
71 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_ACTIVE_ON_INSERTING (0x00000004U)
72 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_VOLTAGE_SELECTION (0x00000008U)
73 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_FREQUENCY_CHANGE (0x00000010U)
74 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_BAUD_RATE_CHANGE (0x00000020U)
75 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_NEGOTIATION (0x00000040U)
76 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_PPS (0x00000080U)
77 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_CAN_SET_IN_STOP_MODE (0x00000100U)
78 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_NAD_VLAUE (0x00000200U)
79 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_IFSD_EXCHANGE_AS_FIRST (0x00000400U)
80 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_TPDU_LEVEL_EXCHANGES (0x00010000U)
81 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_SHORT_APDU_LEVEL_EXCHANGES (0x00020000U)
82 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_SHORT_EXTENDED_APDU_LEVEL_EXCHANGES (0x00040000U)
83 #define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_SUPPORT_SUPPEND (0x00100000U)
84 
85 /* The PIN support in CCID device class-specific descriptor */
86 #define USB_DEVICE_CCID_DESCRIPTOR_PIN_SUPPORT_BM_NO (0x00U)
87 #define USB_DEVICE_CCID_DESCRIPTOR_PIN_SUPPORT_BM_VERIFICATION_SUPPORTED (0x01U)
88 #define USB_DEVICE_CCID_DESCRIPTOR_PIN_SUPPORT_BM_MODIFICATION_SUPPORTED (0x02U)
89 
90 /*! @}*/
91 
92 /*! @brief CCID device class-specific control pipe requests */
93 #define USB_DEVICE_CCID_ABORT (0x01U)
94 #define USB_DEVICE_CCID_GET_CLOCK_FREQUENCIES (0x02U)
95 #define USB_DEVICE_CCID_GET_DATA_RATES (0x03U)
96 
97 /*! @brief The message type of CCID device class-specific bulk-out pipe (Command pipe) */
98 #define USB_DEVICE_CCID_PC_TO_RDR_ICCPOWERON (0x62U)
99 #define USB_DEVICE_CCID_PC_TO_RDR_ICCPOWEROFF (0x63U)
100 #define USB_DEVICE_CCID_PC_TO_RDR_GETSLOTSTATUS (0x65U)
101 #define USB_DEVICE_CCID_PC_TO_RDR_XFRBLOCK (0x6FU)
102 #define USB_DEVICE_CCID_PC_TO_RDR_GETPARAMETERS (0x6CU)
103 #define USB_DEVICE_CCID_PC_TO_RDR_RESETPARAMETERS (0x6DU)
104 #define USB_DEVICE_CCID_PC_TO_RDR_SETPARAMETERS (0x61U)
105 #define USB_DEVICE_CCID_PC_TO_RDR_ESCAPE (0x6BU)
106 #define USB_DEVICE_CCID_PC_TO_RDR_ICCCLOCK (0x6EU)
107 #define USB_DEVICE_CCID_PC_TO_RDR_T0APDU (0x6AU)
108 #define USB_DEVICE_CCID_PC_TO_RDR_SECURE (0x69U)
109 #define USB_DEVICE_CCID_PC_TO_RDR_MECHANICAL (0x71U)
110 #define USB_DEVICE_CCID_PC_TO_RDR_ABORT (0x72U)
111 #define USB_DEVICE_CCID_PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY (0x73U)
112 
113 /*! @brief The message type of CCID device class-specific bulk-in pipe (Response pipe) */
114 #define USB_DEVICE_CCID_RDR_TO_PC_DATABLOCK (0x80U)
115 #define USB_DEVICE_CCID_RDR_TO_PC_SLOTSTATUS (0x81U)
116 #define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_RUNNING (0x00U)
117 #define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_STOPPED_IN_L (0x01U)
118 #define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_STOPPED_IN_H (0x02U)
119 #define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_STOPPED_UNKNOWN (0x03U)
120 #define USB_DEVICE_CCID_RDR_TO_PC_PARAMETERS (0x82U)
121 #define USB_DEVICE_CCID_PROTOCOL_NUMBER_T0 (0x00U)
122 #define USB_DEVICE_CCID_PROTOCOL_NUMBER_T1 (0x01U)
123 #define USB_DEVICE_CCID_RDR_TO_PC_ESCAPE (0x83U)
124 #define USB_DEVICE_CCID_RDR_TO_PC_DATARATEANDCLOCKFREQUENCY (0x84U)
125 
126 /*! @brief The message type of CCID device class-specific interrupt-in pipe */
127 #define USB_DEVICE_CCID_RDR_TO_PC_NOTIFYSLOTCHANGE (0x50U)
128 #define USB_DEVICE_CCID_RDR_TO_PC_HARDWAREERROR (0x51U)
129 
130 /*! @brief Reporting slot error and slot status registers in bulk-in messages */
131 /* Slot error register when bmCommandStatus = 1U */
132 #define USB_DEVICE_CCID_SLOT_ERROR_COMMAND_NOT_SUPPORTED (0x00U)
133 #define USB_DEVICE_CCID_SLOT_ERROR_BAD_LENGTH (0x01U)
134 #define USB_DEVICE_CCID_SLOT_ERROR_SLOT_NOT_EXIST (0x05U)
135 #define USB_DEVICE_CCID_SLOT_ERROR_POWER_SELECT (0x07U)
136 #define USB_DEVICE_CCID_SLOT_ERROR_PROTOCOL_INVALID (0x07U)
137 #define USB_DEVICE_CCID_SLOT_ERROR_BAD_LEVEL_PARAMETER (0x08U)
138 #define USB_DEVICE_CCID_SLOT_ERROR_FI_DI_INVALID (0x0AU)
139 #define USB_DEVICE_CCID_SLOT_ERROR_INVALID_TCCKTS_PARAMETER (0x0BU)
140 #define USB_DEVICE_CCID_SLOT_ERROR_GUARD_TIME_NOT_SUPPORTED (0x0CU)
141 #define USB_DEVICE_CCID_SLOT_ERROR_xWI_INVALID (0x0DU)
142 #define USB_DEVICE_CCID_SLOT_ERROR_CLOCK_STOP_INVALID (0x0EU)
143 #define USB_DEVICE_CCID_SLOT_ERROR_IFSC_SIZE_INVALID (0x0FU)
144 #define USB_DEVICE_CCID_SLOT_ERROR_NAD_VALUE_INVALID (0x10U)
145 
146 #define USB_DEVICE_CCID_SLOT_ERROR_CMD_ABORTED (0xFFU)
147 #define USB_DEVICE_CCID_SLOT_ERROR_ICC_MUTE (0xFEU)
148 #define USB_DEVICE_CCID_SLOT_ERROR_XFR_PARITY_ERROR (0xFDU)
149 #define USB_DEVICE_CCID_SLOT_ERROR_XFR_OVERRUN (0xFCU)
150 #define USB_DEVICE_CCID_SLOT_ERROR_HW_ERROR (0xFBU)
151 #define USB_DEVICE_CCID_SLOT_ERROR_BAD_ATR_TS (0xF8U)
152 #define USB_DEVICE_CCID_SLOT_ERROR_BAD_ATR_TCK (0xF7U)
153 #define USB_DEVICE_CCID_SLOT_ERROR_ICC_PROTOCOL_NOT_SUPPORTED (0xF6U)
154 #define USB_DEVICE_CCID_SLOT_ERROR_ICC_CLASS_NOT_SUPPORTED (0xF5U)
155 #define USB_DEVICE_CCID_SLOT_ERROR_PROCEDURE_BYTE_CONFICT (0xF4U)
156 #define USB_DEVICE_CCID_SLOT_ERROR_DEACTIVATED_PROCTOCL (0xF3U)
157 #define USB_DEVICE_CCID_SLOT_ERROR_BUSY_WITH_AUTO_SEQUENCE (0xF2U)
158 #define USB_DEVICE_CCID_SLOT_ERROR_PIN_TIMEOUT (0xF0U)
159 #define USB_DEVICE_CCID_SLOT_ERROR_PIN_CANCELLED (0xEFU)
160 #define USB_DEVICE_CCID_SLOT_ERROR_CMD_SLOT_BUSY (0xE0U)
161 
162 #define USB_DEVICE_CCID_SLOT_ERROR_CMD_NOT_ABORTED (0xC0U)
163 
164 /* CCID slot status code */
165 #define USB_DEVICE_CCID_SLOT_STATUS_ICC_STATUS_SHIFT (0x00U)
166 #define USB_DEVICE_CCID_SLOT_STATUS_ICC_STATUS_MASK (0x03U)
167 #define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_SHIFT (0x06U)
168 #define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_MASK (0xC0U)
169 
170 /* bmICCStatus */
171 #define USB_DEVICE_CCID_SLOT_STATUS_ICC_PRESENT_ACTIVE (0x00U)
172 #define USB_DEVICE_CCID_SLOT_STATUS_ICC_PRESENT_INACTIVE (0x01U)
173 #define USB_DEVICE_CCID_SLOT_STATUS_ICC_NOT_PRESENT (0x02U)
174 
175 /* bmCommandStatus */
176 #define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_PROCESSED_NO_ERROR (0x00U)
177 #define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_FAILED (0x40U)
178 #define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_TIME_EXTENSION_REQUESTED (0x80U)
179 
180 /*! @brief The command header length of the bulk-out pipe message. */
181 #define USB_DEVICE_CCID_COMMAND_HEADER_LENGTH (0x0AU)
182 /*! @brief The response header length of the bulk-in pipe message. */
183 #define USB_DEVICE_CCID_RESPONSE_HEADER_LENGTH (0x0AU)
184 
185 /*!
186  * @brief Common command structure of the command message in the bulk-out pipe.
187  *
188  */
189 STRUCT_PACKED
190 struct _usb_device_ccid_common_command
191 {
192     uint8_t bMessageType; /*!< The message type */
193     uint32_t dwLength;    /*!< Message-specific data length */
194     uint8_t bSlot;        /*!< Identifies the slot number for this command */
195     uint8_t bSeq;         /*!< Sequence number for command */
196     uint8_t bParameter1;  /*!< Parameter1 of the message, message-specific */
197     uint8_t bParameter2;  /*!< Parameter2 of the message, message-specific */
198     uint8_t bParameter3;  /*!< Parameter3 of the message, message-specific */
199 } STRUCT_UNPACKED;
200 typedef struct _usb_device_ccid_common_command usb_device_ccid_common_command_t;
201 
202 /*!
203  * @brief ICC power on command structure of the command message in the bulk-out pipe.
204  *
205  * A PC_to_RDR_IccPowerOn message to an inactive slot returns an Answer-To-Reset (ATR) data.
206  *
207  * The response to this command message is the RDR_to_PC_DataBlock response message and the
208  * data returned is the Answer To Reset (ATR) data.
209  */
210 STRUCT_PACKED
211 struct _usb_device_ccid_power_on_command
212 {
213     uint8_t bMessageType; /*!< The message type */
214     uint32_t dwLength;    /*!< Message-specific data length */
215     uint8_t bSlot;        /*!< Identifies the slot number for this command */
216     uint8_t bSeq;         /*!< Sequence number for command */
217     uint8_t bPowerSelect; /*!< Voltage that is applied to the ICC */
218     uint8_t bRFU[2];      /*!< Reserved for Future Use */
219 } STRUCT_UNPACKED;
220 typedef struct _usb_device_ccid_power_on_command usb_device_ccid_power_on_command_t;
221 
222 /*!
223  * @brief ICC power off command structure of the command message in the bulk-out pipe.
224  *
225  * The response to this command message is the RDR_to_PC_SlotStatus response message.
226  */
227 STRUCT_PACKED
228 struct _usb_device_ccid_power_off_command
229 {
230     uint8_t bMessageType; /*!< The message type */
231     uint32_t dwLength;    /*!< Message-specific data length */
232     uint8_t bSlot;        /*!< Identifies the slot number for this command */
233     uint8_t bSeq;         /*!< Sequence number for command */
234     uint8_t bRFU[3];      /*!< Reserved for Future Use */
235 } STRUCT_UNPACKED;
236 typedef struct _usb_device_ccid_power_off_command usb_device_ccid_power_off_command_t;
237 
238 /*!
239  * @brief Gets the slot status command structure of the command message in the bulk-out pipe.
240  *
241  * The response to this command message is the RDR_to_PC_SlotStatus response message.
242  */
243 STRUCT_PACKED
244 struct _usb_device_ccid_get_slot_status_command
245 {
246     uint8_t bMessageType; /*!< The message type */
247     uint32_t dwLength;    /*!< Message-specific data length */
248     uint8_t bSlot;        /*!< Identifies the slot number for this command */
249     uint8_t bSeq;         /*!< Sequence number for command */
250     uint8_t bRFU[3];      /*!< Reserved for Future Use */
251 } STRUCT_UNPACKED;
252 typedef struct _usb_device_ccid_get_slot_status_command usb_device_ccid_get_slot_status_command_t;
253 
254 /*!
255  * @brief Transfer data block command structure of the command message in the bulk-out pipe.
256  *
257  * The block should never exceed the dwMaxCCIDMessageLength-10 in the Class Descriptor.
258  * Parameter bBWI is only used by CCIDs which use the character level and TPDU level of exchange
259  * (as reported in the dwFeatures parameter in the CCID Functional Descriptor) and only for protocol T=1 transfers.
260  *
261  * The response to this command message is the RDR_to_PC_DataBlock response message.
262  *
263  * @note For reference, the absolute maximum block size for a TPDU T=0 block is 260U bytes (5U bytes command; 255U bytes
264  * data),
265  * or for a TPDU T=1 block is 259U bytes, or for a short APDU T=1 block is 261U bytes, or for an extended APDU T=1 block
266  * is 65544U bytes.
267  */
268 STRUCT_PACKED
269 struct _usb_device_ccid_transfer_block_command
270 {
271     uint8_t bMessageType;     /*!< The message type */
272     uint32_t dwLength;        /*!< Size of abData field of this message */
273     uint8_t bSlot;            /*!< Identifies the slot number for this command */
274     uint8_t bSeq;             /*!< Sequence number for command */
275     uint8_t bBWI;             /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */
276     uint16_t wLevelParameter; /*!< Use changes depending on the exchange level reported by the class descriptor in
277                                  dwFeatures field */
278     uint8_t abData[1];        /*!< Data block sent to the CCID */
279 } STRUCT_UNPACKED;
280 typedef struct _usb_device_ccid_transfer_block_command usb_device_ccid_transfer_block_command_t;
281 
282 /*!
283  * @brief Gets the ICC parameter command structure of the command message in the bulk-out pipe.
284  *
285  * The response to this command message is the RDR_to_PC_Parameters response message.
286  */
287 STRUCT_PACKED
288 struct _usb_device_ccid_get_parameters_command
289 {
290     uint8_t bMessageType; /*!< The message type */
291     uint32_t dwLength;    /*!< Message-specific data length */
292     uint8_t bSlot;        /*!< Identifies the slot number for this command */
293     uint8_t bSeq;         /*!< Sequence number for command */
294     uint8_t bRFU[3];      /*!< Reserved for Future use */
295 } STRUCT_UNPACKED;
296 typedef struct _usb_device_ccid_get_parameters_command usb_device_ccid_get_parameters_command_t;
297 
298 /*!
299  * @brief Resets the ICC parameter command structure of the command message in the bulk-out pipe.
300  *
301  * This command resets the slot parameters to their default values.
302  *
303  * The response to this command message is the RDR_to_PC_Parameters response message.
304  */
305 STRUCT_PACKED
306 struct _usb_device_ccid_reset_parameters_command
307 {
308     uint8_t bMessageType; /*!< The message type */
309     uint32_t dwLength;    /*!< Message-specific data length */
310     uint8_t bSlot;        /*!< Identifies the slot number for this command */
311     uint8_t bSeq;         /*!< Sequence number for command */
312     uint8_t bRFU[3];      /*!< Reserved for Future Use */
313 } STRUCT_UNPACKED;
314 typedef struct _usb_device_ccid_reset_parameters_command usb_device_ccid_reset_parameters_command_t;
315 
316 /*!
317  * @brief Sets the ICC parameter command structure of the command message in the bulk-out pipe.
318  *
319  * This command is used to change the parameters for a given slot.
320  * A CCID which has no automatic features (dwFeatures=0, 100h, 200h, or 300h) depends on the driver to send this command
321  * to set the protocol and other parameters to the right values necessary to correctly talk to the ICC located in the
322  * selected slot.
323  * A CCID which has automatic features automatically sets the protocol and certain parameters based on data received
324  * from the ICC (ATR, PPS, IFSD, or proprietary algorithms). The level of automatism and design requirements
325  * determines which parameters the CCID allow the driver to change.
326  * If this command tries to change a parameter which is not changeable, then the CCID does not change any parameters and
327  * the RDR_to_PC_GetParameters response returns a Command Failed status and the bError field contains the offset
328  * of the "offending" parameter.
329  *
330  * The response to this command message is the RDR_to_PC_Parameters response message.
331  */
332 STRUCT_PACKED
333 struct _usb_device_ccid_set_parameters_command
334 {
335     uint8_t bMessageType; /*!< The message type */
336     uint32_t dwLength;    /*!< Size of abProtocolDataStructure field of this message */
337     uint8_t bSlot;        /*!< Identifies the slot number for this command */
338     uint8_t bSeq;         /*!< Sequence number for command */
339     uint8_t bProtocolNum; /*!< Specifies what protocol data structure follows. 00h = Structure for protocol T=0, 01h =
340                              Structure for protocol T=1 */
341     uint8_t bRFU[2];      /*!< Reserved for Future Use */
342     uint8_t abProtocolDataStructure[1]; /*!< Protocol Data Structure. For T = 0U, see
343                                            usb_device_ccid_set_parameters_t0_command_t, for T = 1U, see
344                                            usb_device_ccid_set_parameters_t1_command_t. */
345 } STRUCT_UNPACKED;
346 typedef struct _usb_device_ccid_set_parameters_command usb_device_ccid_set_parameters_command_t;
347 
348 /*!
349  * @brief Sets the ICC(T=0) parameter command structure of the command message in the bulk-out pipe.
350  *
351  * Protocol Data Structure for Protocol T=0 (bProtocolNum=0) (dwLength=00000005h).
352  *
353  * The response to this command message is the RDR_to_PC_Parameters response message.
354  */
355 STRUCT_PACKED
356 struct _usb_device_ccid_set_parameters_t0_command
357 {
358     uint8_t bMessageType;      /*!< The message type */
359     uint32_t dwLength;         /*!< (dwLength = 0x05U) */
360     uint8_t bSlot;             /*!< Identifies the slot number for this command */
361     uint8_t bSeq;              /*!< Sequence number for command */
362     uint8_t bProtocolNum;      /*!< Structure for protocol T=0 */
363     uint8_t bRFU[2];           /*!< Reserved for Future Use */
364     uint8_t bmFindexDindex;    /*!< Bit7~4 - Fi, Bit3~0 - Di. */
365     uint8_t bmTCCKST0;         /*!< Bit1 - Convention used(0U for direct, 1U for inverse), other bits is 0*/
366     uint8_t bGuardTimeT0;      /*!< Extra guard time between two characters. */
367     uint8_t bWaitingIntegerT0; /*!< WI for T= 0U used to define WWT */
368     uint8_t bClockStop;        /*!< ICC Clock Stop Support */
369 } STRUCT_UNPACKED;
370 typedef struct _usb_device_ccid_set_parameters_t0_command usb_device_ccid_set_parameters_t0_command_t;
371 
372 /*!
373  * @brief Sets the ICC(T=1) parameter command structure of the command message in the bulk-out pipe.
374  *
375  * Protocol Data Structure for Protocol T=1 (bProtocolNum=1) (dwLength=00000007h)
376  *
377  * The response to this command message is the RDR_to_PC_Parameters response message.
378  */
379 STRUCT_PACKED
380 struct _usb_device_ccid_set_parameters_t1_command
381 {
382     uint8_t bMessageType;   /*!< The message type */
383     uint32_t dwLength;      /*!< (dwLength = 0x07U) */
384     uint8_t bSlot;          /*!< Identifies the slot number for this command */
385     uint8_t bSeq;           /*!< Sequence number for command */
386     uint8_t bProtocolNum;   /*!< Structure for protocol T=1 */
387     uint8_t bRFU[2];        /*!< Reserved for Future Use */
388     uint8_t bmFindexDindex; /*!< Bit7~4 - Fi, Bit3~0 - Di. */
389     uint8_t bmTCCKST1; /*!< Bit0 - Checksum type(0U for LRC, 1U for CRC). Bit1 - Convention used(0U for direct, 1U for
390                           inverse), Bit7~2 - 0b000100 */
391     uint8_t bGuardTimeT1;        /*!< Extra guard time. */
392     uint8_t bmWaitingIntegersT1; /*!< Bit7~4 - BWI(0~9 valid), Bit3~0 - CWI(0~0xF valid) */
393     uint8_t bClockStop;          /*!< ICC Clock Stop Support */
394     uint8_t bIFSC;               /*!< Size of negotiated IFSC */
395     uint8_t bNadValue; /*!< Value = 0x00U if CCID doesn't support a value other then the default value. Else value
396                           respects ISO/IEC 7816-3, 9.4.2.1 */
397 } STRUCT_UNPACKED;
398 typedef struct _usb_device_ccid_set_parameters_t1_command usb_device_ccid_set_parameters_t1_command_t;
399 
400 /*! @brief Sets the ICC parameter command union of the command message in the bulk-out pipe. */
401 typedef union _usb_device_ccid_set_parameters_command_common
402 {
403     usb_device_ccid_set_parameters_command_t common; /*!< Set ICC parameter common structure */
404     usb_device_ccid_set_parameters_t0_command_t t0;  /*!< Set ICC parameter structure for T0 */
405     usb_device_ccid_set_parameters_t1_command_t t1;  /*!< Set ICC parameter structure for T1 */
406 } usb_device_ccid_set_parameters_command_common_t;
407 
408 /*!
409  * @brief Escape command structure of the command message in the bulk-out pipe.
410  *
411  * This command allows the CCID manufacturer to define and access extended features.
412  * Information sent via this command is processed by the CCID control logic.
413  *
414  * The response to this command message is the RDR_to_PC_Escape response message.
415  */
416 STRUCT_PACKED
417 struct _usb_device_ccid_escape_command
418 {
419     uint8_t bMessageType; /*!< The message type */
420     uint32_t dwLength;    /*!< Message-specific data length */
421     uint8_t bSlot;        /*!< Identifies the slot number for this command */
422     uint8_t bSeq;         /*!< Sequence number for command */
423     uint8_t bRFU[3];      /*!< Reserved for future use */
424     uint8_t abData[1];    /*!< Size of abData field of this message */
425 } STRUCT_UNPACKED;
426 typedef struct _usb_device_ccid_escape_command usb_device_ccid_escape_command_t;
427 
428 /*!
429  * @brief Controls the ICC clock command structure of the command message in the bulk-out pipe.
430  *
431  * This command stops or restarts the clock.
432  *
433  * The response to this command message is the RDR_to_PC_SlotStatus response message.
434  */
435 STRUCT_PACKED
436 struct _usb_device_ccid_clock_command
437 {
438     uint8_t bMessageType;  /*!< The message type */
439     uint32_t dwLength;     /*!< Message-specific data length */
440     uint8_t bSlot;         /*!< Identifies the slot number for this command */
441     uint8_t bSeq;          /*!< Sequence number for command */
442     uint8_t bClockCommand; /*!< 0x00U - Restart clock, 0x01U - Stop clock in the state shown in the bClockStop field of
443                               the PC_to_RDR_SetParameters command and RDR_to_PC_Parameters message.*/
444     uint8_t bRFU[2];       /*!< Reserved for future use */
445 } STRUCT_UNPACKED;
446 typedef struct _usb_device_ccid_clock_command usb_device_ccid_clock_command_t;
447 
448 /*!
449  * @brief Controls the ICC clock command structure of the command message in the bulk-out pipe.
450  *
451  * This command changes the parameters used to perform the transportation of APDU messages by the T=0 protocol.
452  * It effects the CLA (class) byte used when issuing a Get Response command or a Envelope command to the ICC.
453  *
454  * This command is slot-specific. It only effects the slot specified in the bSlot field.
455  * Slots, when not powered, do not change back to using the default behaviour defined in the CCID class descriptor.
456  * Any newly inserted ICC has the default behaviour until this command is issued for its slot.
457  *
458  * The response to this command message is the RDR_to_PC_SlotStatus response message.
459  */
460 STRUCT_PACKED
461 struct _usb_device_ccid_t0_apdu_command
462 {
463     uint8_t bMessageType;      /*!< The message type */
464     uint32_t dwLength;         /*!< Message-specific data length */
465     uint8_t bSlot;             /*!< Identifies the slot number for this command */
466     uint8_t bSeq;              /*!< Sequence number for command */
467     uint8_t bmChanges;         /*!<
468                                 * The value is bitwise OR operation.
469                                 * Bit 0U is associated with field bClassGetResponse
470                                 * Bit 1U is associated with field bClassEnvelope
471                                 * Other bits are RFU. */
472     uint8_t bClassGetResponse; /*!< Value to force the class byte of the header in a get response command */
473     uint8_t bClassEnvelope;    /*!< Value to force the class byte of the header in a envelope command */
474 } STRUCT_UNPACKED;
475 typedef struct _usb_device_ccid_t0_apdu_command usb_device_ccid_t0_apdu_command_t;
476 
477 /*!
478  * @brief Secures the command structure of the command message in the bulk-out pipe.
479  *
480  * This is a command message to allow entering the PIN for verification or modification.
481  *
482  * The response to this command message is the RDR_to_PC_DataBlock response message.
483  */
484 STRUCT_PACKED
485 struct _usb_device_ccid_secure_command
486 {
487     uint8_t bMessageType;     /*!< The message type */
488     uint32_t dwLength;        /*!< Size of abData field of this message */
489     uint8_t bSlot;            /*!< Identifies the slot number for this command */
490     uint8_t bSeq;             /*!< Sequence number for command */
491     uint8_t bBWI;             /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */
492     uint16_t wLevelParameter; /*!< Use changes depending on the exchange level reported by CCID in the functional
493                                  descriptor */
494     uint8_t abData[1];        /*!<
495                                * The value depends of wLevelParameters.
496                                * When wLevelParameters is 0000h or 0001h abData = abPINOperationDataStructure.
497                                * For other values of wLevelParameters this field is the continuation of the previously sent
498                                * PC_to_RDR_Secure.
499                                */
500 } STRUCT_UNPACKED;
501 typedef struct _usb_device_ccid_secure_command usb_device_ccid_secure_command_t;
502 
503 /*!
504  * @brief Secures the PIN operation command structure of the command message in the bulk-out pipe.
505  *
506  * This is a command message to allow entering the PIN for verification or modification.
507  *
508  * The response to this command message is the RDR_to_PC_DataBlock response message.
509  */
510 STRUCT_PACKED
511 struct _usb_device_ccid_secure_pin_operation_command
512 {
513     uint8_t bMessageType;          /*!< The message type */
514     uint32_t dwLength;             /*!< 1U + Size of abPINDataStructure field of this message */
515     uint8_t bSlot;                 /*!< Identifies the slot number for this command */
516     uint8_t bSeq;                  /*!< Sequence number for command */
517     uint8_t bBWI;                  /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */
518     uint16_t wLevelParameter;      /*!< Use changes depending on the exchange level reported by CCID in the functional
519                                       descriptor */
520     uint8_t bPINOperation;         /*!<
521                                     * Used to indicate the PIN operation:
522                                     *   00h: PIN Verification
523                                     *   01h: PIN Modification
524                                     *   02h: Transfer PIN from secure CCID buffer
525                                     *   03h: Wait ICC response
526                                     *   04h: Cancel PIN function
527                                     *   05h: Re-send last I-Block, valid only if T = 1.
528                                     *   06h: Send next part of APDU, valid only T = 1.
529                                     */
530     uint8_t abPINDataStructure[1]; /* PIN Verification Data Structure or PIN Modification Data Structure */
531 } STRUCT_UNPACKED;
532 typedef struct _usb_device_ccid_secure_pin_operation_command usb_device_ccid_secure_pin_operation_command_t;
533 
534 /*!
535  * @brief Secures the PIN verification operation command structure of the command message in the bulk-out pipe.
536  *
537  * This is a command message to allow entering the PIN for verification.
538  *
539  * The response to this command message is the RDR_to_PC_DataBlock response message.
540  */
541 STRUCT_PACKED
542 struct _usb_device_ccid_seucre_pin_verification_command
543 {
544     uint8_t bMessageType;       /*!< The message type */
545     uint32_t dwLength;          /*!< 12U + Size of abPINApdu field of this message */
546     uint8_t bSlot;              /*!< Identifies the slot number for this command */
547     uint8_t bSeq;               /*!< Sequence number for command */
548     uint8_t bBWI;               /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */
549     uint16_t wLevelParameter;   /*!< Use changes depending on the exchange level reported by CCID in the functional
550                                    descriptor */
551     uint8_t bPINOperation;      /*!<
552                                  * Used to indicate the PIN operation:
553                                  *   00h: PIN Verification
554                                  *   01h: PIN Modification
555                                  *   02h: Transfer PIN from secure CCID buffer
556                                  *   03h: Wait ICC response
557                                  *   04h: Cancel PIN function
558                                  *   05h: Re-send last I-Block, valid only if T = 1.
559                                  *   06h: Send next part of APDU, valid only T = 1.
560                                  */
561     uint8_t bTimeOut;           /*!< Number of seconds */
562     uint8_t bmFormatString;     /*!< Several parameters for the PIN format options */
563     uint8_t bmPINBlockString;   /*!< Defines the length in bytes of the PIN block to present in the APDU command */
564     uint8_t bmPINLengthFormat;  /*!< Allows the insertion of the PIN length in the APDU command */
565     uint16_t wPINMaxExtraDigit; /*!< Bit15~8 - Minimum PIN size in digit, Bit7~0 - Maximum PIN size in digit */
566     uint8_t bEntryValidationCondition; /*!< The value is a bit wise OR operation. 01h - Maximum size reached, 02h -
567                                           Validation key pressed, 04h - Timeout occurred*/
568     uint8_t bNumberMessage;            /*!< Number of messages to display for the PIN Verification management. */
569     uint16_t wLangId;                  /*!< Language used to display the messages.*/
570     uint8_t bMsgIndex;                 /*!< Message index in the Reader CCID message table (should be 00h). */
571     uint8_t bTeoPrologue;              /*!< T=1 I-block prologue field to use. */
572     uint8_t abPINApdu[1];              /*!< APDU to send to the ICC */
573 } STRUCT_UNPACKED;
574 typedef struct _usb_device_ccid_seucre_pin_verification_command usb_device_ccid_seucre_pin_verification_command_t;
575 
576 /*!
577  * @brief Secures the PIN modification operation command structure of the command message in the bulk-out pipe.
578  *
579  * This is a command message to allow entering the PIN for modification.
580  *
581  * The response to this command message is the RDR_to_PC_DataBlock response message.
582  */
583 STRUCT_PACKED
584 struct _usb_device_ccid_secure_pin_modification_command
585 {
586     uint8_t bMessageType;        /*!< The message type */
587     uint32_t dwLength;           /*!< 20U + Size of abPINApdu field of this message */
588     uint8_t bSlot;               /*!< Identifies the slot number for this command */
589     uint8_t bSeq;                /*!< Sequence number for command */
590     uint8_t bBWI;                /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */
591     uint16_t wLevelParameter;    /*!< Use changes depending on the exchange level reported by CCID in the functional
592                                     descriptor */
593     uint8_t bPINOperation;       /*!<
594                                   * Used to indicate the PIN operation:
595                                   *   00h: PIN Verification
596                                   *   01h: PIN Modification
597                                   *   02h: Transfer PIN from secure CCID buffer
598                                   *   03h: Wait ICC response
599                                   *   04h: Cancel PIN function
600                                   *   05h: Re-send last I-Block, valid only if T = 1.
601                                   *   06h: Send next part of APDU, valid only T = 1.
602                                   */
603     uint8_t bTimeOut;            /*!< Number of seconds */
604     uint8_t bmFormatString;      /*!< Several parameters for the PIN format options */
605     uint8_t bmPINBlockString;    /*!< Define the length of the PIN to present in the APDU command */
606     uint8_t bmPINLengthFormat;   /*!< Allows the length PIN insertion in the APDU command */
607     uint8_t bInsertionOffsetOld; /*!< Insertion position offset in byte for the current PIN */
608     uint8_t bInsertionOffsetNew; /*!< Insertion position offset in byte for the new PIN */
609     uint16_t wPINMaxExtraDigit;  /*!< Bit15~8 - Minimum PIN size in digit, Bit7~0 - Maximum PIN size in digit */
610     uint8_t bConfirmPIN;         /*!< Indicates if a confirmation is requested before acceptance of a new PIN */
611     uint8_t bEntryValidationCondition; /*!< The value is a bit wise OR operation. 01h - Maximum size reached, 02h -
612                                           Validation key pressed, 04h - Timeout occurred*/
613     uint8_t bNumberMessage;            /*!< Number of messages to display for the PIN Verification management. */
614     uint16_t wLangId;                  /*!< Language used to display the messages.*/
615     uint8_t bMsgIndex1;                /*!< Message index in the Reader message table(should be 00h or 01h). */
616     uint8_t bMsgIndex2;                /*!< Message index in the Reader message table(should be 01h or 02h). */
617     uint8_t bMsgIndex3;                /*!< Message index in the Reader message table(should be 02h). */
618     uint8_t bTeoPrologue[3];           /*!< T=1 I-block prologue field to use. */
619     uint8_t abPINApdu[1];              /*!< APDU to send to the ICC */
620 } STRUCT_UNPACKED;
621 typedef struct _usb_device_ccid_secure_pin_modification_command usb_device_ccid_secure_pin_modification_command_t;
622 
623 /*!
624  * @brief Manages the motorized type CCID functionality command structure of the command message in the bulk-out pipe.
625  *
626  * This command is used to manage motorized type CCID functionality.
627  *
628  * The response to this command message is the RDR_to_PC_SlotStatus response message.
629  */
630 STRUCT_PACKED
631 struct _usb_device_ccid_mechanical_command
632 {
633     uint8_t bMessageType; /*!< The message type */
634     uint32_t dwLength;    /*!< Message-specific data length */
635     uint8_t bSlot;        /*!< Identifies the slot number for this command */
636     uint8_t bSeq;         /*!< Sequence number for command */
637     uint8_t bFunction;    /*!< This value corresponds to the mechanical function being requested */
638     uint8_t bRFU[2];      /*!< Reserved for Future Use */
639 } STRUCT_UNPACKED;
640 typedef struct _usb_device_ccid_mechanical_command usb_device_ccid_mechanical_command_t;
641 
642 /*!
643  * @brief Aborts the command structure of the command message in the bulk-out pipe.
644  *
645  * This command is used with the control pipe abort request to tell the
646  * CCID to stop any current transfer at the specified slot and return to a state
647  * where the slot is ready to accept a new command pipe Bulk-OUT message.
648  *
649  * The response to this command message is the RDR_to_PC_SlotStatus response message.
650  */
651 STRUCT_PACKED
652 struct _usb_device_ccid_abort_command
653 {
654     uint8_t bMessageType; /*!< The message type */
655     uint32_t dwLength;    /*!< Message-specific data length */
656     uint8_t bSlot;        /*!< Identifies the slot number for this command */
657     uint8_t bSeq;         /*!< Sequence number for command */
658     uint8_t bRFU[3];      /*!< Reserved for future use */
659 } STRUCT_UNPACKED;
660 typedef struct _usb_device_ccid_abort_command usb_device_ccid_abort_command_t;
661 
662 /*!
663  * @brief Sets data rate and clock frequency command structure of the command message in the bulk-out pipe.
664  *
665  * This command is used to manually set the data rate and clock frequency of a specific slot.
666  *
667  * The response to this command message is the RDR_to_PC_SlotStatus response message.
668  */
669 STRUCT_PACKED
670 struct _usb_device_ccid_set_data_rate_and_clock_frequency_command
671 {
672     uint8_t bMessageType;      /*!< The message type */
673     uint32_t dwLength;         /*!< Message-specific data length(8U bytes) */
674     uint8_t bSlot;             /*!< Identifies the slot number for this command */
675     uint8_t bSeq;              /*!< Sequence number for command */
676     uint8_t bRFU[3];           /*!< Reserved for Future Use */
677     uint32_t dwClockFrequency; /*!< ICC clock frequency in kHz. This is an integer value */
678     uint32_t dwDataRate;       /*!< ICC data rate in BPD */
679 } STRUCT_UNPACKED;
680 typedef struct _usb_device_ccid_set_data_rate_and_clock_frequency_command
681     usb_device_ccid_set_data_rate_and_clock_frequency_command_t;
682 
683 /*!
684  * @brief Common response structure to respond a command message in the bulk-in pipe.
685  *
686  */
687 STRUCT_PACKED
688 struct _usb_device_ccid_common_response
689 {
690     uint8_t bMessageType; /*!< The message type */
691     uint32_t dwLength;    /*!< Message-specific data length */
692     uint8_t bSlot;        /*!< Identifies the slot number for this command */
693     uint8_t bSeq;         /*!< Sequence number for the corresponding command */
694     uint8_t bStatus;      /*!< Slot status register */
695     uint8_t bError;       /*!< Slot error register */
696     uint8_t bParameter1;  /*!< Parameter1 of the message, message-specific */
697 } STRUCT_UNPACKED;
698 typedef struct _usb_device_ccid_common_response usb_device_ccid_common_response_t;
699 
700 /*!
701  * @brief Data block response structure to respond a command message in the bulk-in pipe.
702  *
703  * The device in response to the following command messages: "PC_to_RDR_IccPowerOn", "PC_to_RDR_Secure" and
704  * "PC_to_RDR_XfrBlock" sends this response message.
705  * For "PC_to_RDR_IccPowerOn" this response message is the answer to reset (ATR) data associated with the ICC power on.
706  * In other use cases, the response message has the following format: the response data contains the
707  * optional data returned by the ICC, followed by the 2U byte-size status words SW1-SW2.
708  */
709 STRUCT_PACKED
710 struct _usb_device_ccid_data_block_response
711 {
712     uint8_t bMessageType;    /*!< The message type */
713     uint32_t dwLength;       /*!< Message-specific data length */
714     uint8_t bSlot;           /*!< Identifies the slot number for this command */
715     uint8_t bSeq;            /*!< Sequence number for the corresponding command */
716     uint8_t bStatus;         /*!< Slot status register */
717     uint8_t bError;          /*!< Slot error register */
718     uint8_t bChainParameter; /*!< Use changes depending on the exchange level reported by the class descriptor in
719                                 dwFeatures field */
720     uint8_t abData[1];       /*!< This field contains the data returned by the CCID. */
721 } STRUCT_UNPACKED;
722 typedef struct _usb_device_ccid_data_block_response usb_device_ccid_data_block_response_t;
723 
724 /*!
725  * @brief Sends a slot status response structure to respond a command message in the bulk-in pipe.
726  *
727  * The device in response to the following command messages: "PC_to_RDR_IccPowerOff", "PC_to_RDR_GetSlotStatus",
728  * "PC_to_RDR_IccClock", "PC_to_RDR_T0APDU" and, "PC_to_RDR_Mechanical" sends this response message.
729  * Also, the device sends this response message when it has completed aborting a slot after receiving
730  * both the Class Specific ABORT request and PC_to_RDR_Abort command message.
731  */
732 STRUCT_PACKED
733 struct _usb_device_ccid_slot_status_response
734 {
735     uint8_t bMessageType; /*!< The message type */
736     uint32_t dwLength;    /*!< Message-specific data length */
737     uint8_t bSlot;        /*!< Identifies the slot number for this command */
738     uint8_t bSeq;         /*!< Sequence number for the corresponding command */
739     uint8_t bStatus;      /*!< Slot status register */
740     uint8_t bError;       /*!< Slot error register */
741     uint8_t bClockStatus; /*!< 0x00U - Clock running, 0x01U - Clock stopped in L, 0x02U - clock stopped in H, and 0x03U
742                              - clock stopped in an unknown state.*/
743 } STRUCT_UNPACKED;
744 typedef struct _usb_device_ccid_slot_status_response usb_device_ccid_slot_status_response_t;
745 
746 /*!
747  * @brief ICC parameter response structure to respond a command message in the bulk-in pipe.
748  *
749  * The device in response to the following command messages: "PC_to_RDR_GetParameters", "PC_to_RDR_ResetParameters",
750  * and, "PC_to_RDR_SetParameters" sends this response message.
751  */
752 STRUCT_PACKED
753 struct _usb_device_ccid_parameters_response
754 {
755     uint8_t bMessageType;               /*!< The message type */
756     uint32_t dwLength;                  /*!< Size of abProtocolDataStructure field of this message */
757     uint8_t bSlot;                      /*!< Identifies the slot number for this command */
758     uint8_t bSeq;                       /*!< Sequence number for the corresponding command */
759     uint8_t bStatus;                    /*!< Slot status register */
760     uint8_t bError;                     /*!< Slot error register */
761     uint8_t bProtocolNum;               /*!< 0x00U = Structure for protocol T=0, 0x01U = Structure for protocol T=1 */
762     uint8_t abProtocolDataStructure[1]; /*!< Protocol Data Structure */
763 } STRUCT_UNPACKED;
764 typedef struct _usb_device_ccid_parameters_response usb_device_ccid_parameters_response_t;
765 
766 /*!
767  * @brief ICC T0 parameter response structure to respond a command message in the bulk-in pipe.
768  *
769  * The device in response to the following command messages: "PC_to_RDR_GetParameters", "PC_to_RDR_ResetParameters",
770  * and, "PC_to_RDR_SetParameters" sends this response message.
771  */
772 STRUCT_PACKED
773 struct _usb_device_ccid_parameters_T0_response
774 {
775     uint8_t bMessageType;      /*!< The message type */
776     uint32_t dwLength;         /*!< The value is 0x05U */
777     uint8_t bSlot;             /*!< Identifies the slot number for this command */
778     uint8_t bSeq;              /*!< Sequence number for the corresponding command */
779     uint8_t bStatus;           /*!< Slot status register */
780     uint8_t bError;            /*!< Slot error register */
781     uint8_t bProtocolNum;      /*!< 0x00U = Structure for protocol T=0 */
782     uint8_t bmFindexDindex;    /*!< Bit7~4 - Fi, Bit3~0 - Di. */
783     uint8_t bmTCCKST0;         /*!< Bit1 - Convention used(0U for direct, 1U for inverse), other bits is 0*/
784     uint8_t bGuardTimeT0;      /*!< Extra guard time between two characters. */
785     uint8_t bWaitingIntegerT0; /*!< WI for T= 0U used to define WWT */
786     uint8_t bClockStop;        /*!< ICC Clock Stop Support */
787 } STRUCT_UNPACKED;
788 typedef struct _usb_device_ccid_parameters_T0_response usb_device_ccid_parameters_T0_response_t;
789 
790 /*!
791  * @brief ICC T1 parameter response structure to response a command message in the bulk-in pipe.
792  *
793  * The device in response to the following command messages: "PC_to_RDR_GetParameters", "PC_to_RDR_ResetParameters",
794  * and, "PC_to_RDR_SetParameters" sends this response message.
795  */
796 STRUCT_PACKED
797 struct _usb_device_ccid_parameters_T1_response
798 {
799     uint8_t bMessageType;   /*!< The message type */
800     uint32_t dwLength;      /*!< The value is 0x07U */
801     uint8_t bSlot;          /*!< Identifies the slot number for this command */
802     uint8_t bSeq;           /*!< Sequence number for the corresponding command */
803     uint8_t bStatus;        /*!< Slot status register */
804     uint8_t bError;         /*!< Slot error register */
805     uint8_t bProtocolNum;   /*!< 0x00U = Structure for protocol T=1 */
806     uint8_t bmFindexDindex; /*!< Bit7~4 - Fi, Bit3~0 - Di. */
807     uint8_t bmTCCKST1; /*!< Bit0 - Checksum type(0U for LRC, 1U for CRC). Bit1 - Convention used(0U for direct, 1U for
808                           inverse), Bit7~2 - 0b000100 */
809     uint8_t bGuardTimeT1;        /*!< Extra guard time. */
810     uint8_t bmWaitingIntegersT1; /*!< Bit7~4 - BWI(0~9 valid), Bit3~0 - CWI(0~0xF valid) */
811     uint8_t bClockStop;          /*!< ICC Clock Stop Support */
812     uint8_t bIFSC;               /*!< Size of negotiated IFSC */
813     uint8_t bNadValue; /*!< Value = 0x00U if CCID doesn't support a value other then the default value. Else value
814                           respects ISO/IEC 7816-3, 9.4.2.1 */
815 } STRUCT_UNPACKED;
816 typedef struct _usb_device_ccid_parameters_T1_response usb_device_ccid_parameters_T1_response_t;
817 
818 /*! @brief ICC parameter response union to response a command message in the bulk-in pipe. */
819 typedef union _usb_device_ccid_parameters_response_common
820 {
821     usb_device_ccid_parameters_response_t common; /*!< Response ICC parameter common structure */
822     usb_device_ccid_parameters_T0_response_t t0;  /*!< Response ICC parameter structure for T0 */
823     usb_device_ccid_parameters_T1_response_t t1;  /*!< Response ICC parameter structure for T1 */
824 } usb_device_ccid_parameters_response_common_t;
825 
826 /*!
827  * @brief Response structure to respond the "PC_to_RDR_Escape" command message in the bulk-in pipe.
828  *
829  * The device in response to the following command messages: "PC_to_RDR_Escape" sends this response message.
830  */
831 STRUCT_PACKED
832 struct _usb_device_ccid_escape_response
833 {
834     uint8_t bMessageType; /*!< The message type */
835     uint32_t dwLength;    /*!< Size of abData field of this message */
836     uint8_t bSlot;        /*!< Identifies the slot number for this command */
837     uint8_t bSeq;         /*!< Sequence number for the corresponding command */
838     uint8_t bStatus;      /*!< Slot status register */
839     uint8_t bError;       /*!< Slot error register */
840     uint8_t bRFU;         /*!< Reserved for Future Use */
841     uint8_t abData[1];    /*!< Data sent from CCID */
842 } STRUCT_UNPACKED;
843 typedef struct _usb_device_ccid_escape_response usb_device_ccid_escape_response_t;
844 
845 /*!
846  * @brief Response structure to respond the "PC_to_RDR_SetDataRateAndClockFrequency" command message in the bulk-in
847  * pipe.
848  *
849  * The device in response to the following command messages: "PC_to_RDR_SetDataRateAndClockFrequency" sends this
850  * response message.
851  */
852 STRUCT_PACKED
853 struct _usb_device_ccid_data_rate_and_clock_frequency_response
854 {
855     uint8_t bMessageType;      /*!< The message type */
856     uint32_t dwLength;         /*!< Message-specific data length */
857     uint8_t bSlot;             /*!< Identifies the slot number for this command */
858     uint8_t bSeq;              /*!< Sequence number for the corresponding command */
859     uint8_t bStatus;           /*!< Slot status register */
860     uint8_t bError;            /*!< Slot error register */
861     uint8_t bRFU;              /*!< Reserved for Future Use */
862     uint32_t dwClockFrequency; /*!< Current setting of the ICC clock frequency in KHz. This is an integer value */
863     uint32_t dwDataRate;       /*!< Current setting of the ICC data rate in bps. This is an integer value */
864 } STRUCT_UNPACKED;
865 typedef struct _usb_device_ccid_data_rate_and_clock_frequency_response
866     usb_device_ccid_data_rate_and_clock_frequency_response_t;
867 
868 /*! @brief Notification structure to notify Host the CCID device slot changed */
869 STRUCT_PACKED
870 struct _usb_device_ccid_notify_slot_chnage_notification
871 {
872     uint8_t bMessageType;      /*!< The message type */
873     uint8_t bmSlotICCState[1]; /*!< This field is reported on byte granularity. */
874 } STRUCT_UNPACKED;
875 typedef struct _usb_device_ccid_notify_slot_chnage_notification usb_device_ccid_notify_slot_chnage_notification_t;
876 
877 /*! @brief Notification structure to notify Host a hardware error happened in the CCID device */
878 STRUCT_PACKED
879 struct _usb_device_ccid_hardware_error_notification
880 {
881     uint8_t bMessageType;       /*!< The message type */
882     uint8_t bSlot;              /*!< Identifies the slot number for this command */
883     uint8_t bSeq;               /*!< Sequence number of bulk out command when the hardware error occurred */
884     uint8_t bHardwareErrorCode; /*!< 0x01U - Over current. */
885 } STRUCT_UNPACKED;
886 typedef struct _usb_device_ccid_hardware_error_notification usb_device_ccid_hardware_error_notification_t;
887 
888 /*! @brief The definition to make the length aligned to 4-bytes */
889 #define USB_DEVICE_CCID_BUFFER_4BYTE_ALIGN(n) (((n - 1U) & 0xFFFFFFFCU) + 0x00000004U)
890 
891 /*! @brief USB device CCID transfer structure */
892 typedef struct _usb_device_ccid_transfer_struct
893 {
894     struct _usb_device_ccid_transfer_struct *next;   /*!< Next transfer pointer */
895     uint8_t *buffer;                                 /*!< The transfer buffer address need to be sent */
896     uint32_t length;                                 /*!< The transfer length */
897     usb_device_ccid_slot_status_response_t response; /*!< Response buffer is used when dwLength = 0. */
898 } usb_device_ccid_transfer_struct_t;
899 
900 /*! @brief Available common EVENT types in CCID class callback */
901 typedef enum _usb_device_ccid_event
902 {
903     kUSB_DeviceCcidEventCommandReceived = 0x01U, /*!< Command received or cancelled in BULK OUT pipe */
904     kUSB_DeviceCcidEventResponseSent,            /*!< Response sent in BULK IN pipe */
905     kUSB_DeviceCcidEventGetSlotCount,            /*!< Get the slot count */
906     kUSB_DeviceCcidEventGetSlotStatus,           /*!< Get the slot status, including clock status, ICC present.*/
907     kUSB_DeviceCcidEventCommandAbort,            /*!< Command abort request received from control pipe*/
908     kUSB_DeviceCcidEventGetClockFrequencies,     /*!< Get the clock frequencies */
909     kUSB_DeviceCcidEventGetDataRate,             /*!< Get the data rate */
910     kUSB_DeviceCcidEventSlotChangeSent,          /*!< Slot changed notification send completed */
911     kUSB_DeviceCcidEventHardwareErrorSent,       /*!< Hardware error notification send completed */
912 } usb_device_ccid_event_t;
913 
914 /*! @brief The structure is used to get data rates or clock frequencies if the event is
915  * kUSB_DeviceCcidEventGetClockFrequencies or kUSB_DeviceCcidEventGetDataRate*/
916 typedef struct _usb_device_ccid_control_request_struct
917 {
918     uint8_t *buffer; /*!< The buffer address */
919     uint32_t length; /*!< The data length */
920 } usb_device_ccid_control_request_struct_t;
921 
922 /*! @brief The structure is used to keep the transferred buffer and transferred length if the event is
923  * kUSB_DeviceCcidEventSlotChangeSent or kUSB_DeviceCcidEventHardwareErrorSent*/
924 typedef struct _usb_device_ccid_notification_struct
925 {
926     uint8_t *buffer; /*!< The transferred buffer address */
927     uint32_t length; /*!< The transferred data length */
928 } usb_device_ccid_notification_struct_t;
929 
930 /*! @brief The structure is used to keep the command data and length and get response data and length if the event is
931  * kUSB_DeviceCcidEventCommandReceived*/
932 typedef struct _usb_device_ccid_command_struct
933 {
934     uint8_t *commandBuffer;  /*!< The buffer address kept the command from host */
935     uint32_t commandLength;  /*!< The command length from host */
936     uint8_t *responseBuffer; /*!< The response data need to be sent to host */
937     uint32_t responseLength; /*!< The response data length */
938 } usb_device_ccid_command_struct_t;
939 
940 /*! @brief The structure is used to get the slot status if the event is kUSB_DeviceCcidEventGetSlotStatus*/
941 typedef struct _usb_device_ccid_slot_status_struct
942 {
943     uint8_t slot;        /*!< The slot number need to get */
944     uint8_t present;     /*!< Is present or not */
945     uint8_t clockStatus; /*!< The clock status */
946 } usb_device_ccid_slot_status_struct_t;
947 
948 /*! @brief Slot status, present or not */
949 typedef enum _usb_device_ccid_slot_state
950 {
951     kUSB_DeviceCcidSlotStateNoPresent = 0x00U, /*!< Not present */
952     kUSB_DeviceCcidSlotStatePresent   = 0x01U  /*!< Present */
953 } usb_device_ccid_slot_state_t;
954 
955 /*! @brief Hardware error status */
956 typedef enum _usb_device_ccid_hardware_error
957 {
958     kUSB_DeviceCcidHardwareErrorOverCurrent = 0x01U, /*!< Over current */
959 } usb_device_ccid_hardware_error_t;
960 
961 /*! @brief The CCID device class status structure */
962 typedef struct _usb_device_ccid_struct
963 {
964     usb_device_handle handle;                        /*!< The device handle */
965     usb_device_class_config_struct_t *configStruct;  /*!< The configuration of the class. */
966     usb_device_interface_struct_t *interfaceHandle;  /*!< Current interface handle */
967     usb_device_ccid_transfer_struct_t *transferHead; /*!< Transfer queue for busy*/
968     usb_device_ccid_transfer_struct_t *transferFree; /*!< Transfer queue for idle*/
969     uint8_t commandBuffer[USB_DEVICE_CCID_BUFFER_4BYTE_ALIGN(
970         USB_DEVICE_CONFIG_CCID_MAX_MESSAGE_LENGTH)]; /*!< Command buffer for getting command data from host */
971     usb_device_ccid_transfer_struct_t transfers[USB_DEVICE_CONFIG_CCID_TRANSFER_COUNT]; /*!< Transfer entity */
972     uint8_t slotsChangeBuffer[(USB_DEVICE_CONFIG_CCID_SLOT_MAX * 2 - 1U) / 8 + 1U +
973                               1U]; /*!< The buffer for saving slot status */
974     uint8_t slotsSendingChangeBuffer[(USB_DEVICE_CONFIG_CCID_SLOT_MAX * 2 - 1U) / 8 + 1U +
975                                      1U]; /*!< The buffer is used to notify host the slot status changed */
976     uint8_t slotsSequenceNumber[USB_DEVICE_CONFIG_CCID_SLOT_MAX]; /*!< Save each slot sequence number */
977     usb_device_ccid_hardware_error_notification_t
978         hardwareError;           /*!< The buffer is used to notify host the hardware error happened */
979     uint8_t configuration;       /*!< Current configuration */
980     uint8_t interfaceNumber;     /*!< The interface number of the class */
981     uint8_t alternate;           /*!< Current alternate setting of the interface */
982     uint8_t endpointInterruptIn; /*!< The endpoint number of the interrupt IN pipe */
983     uint8_t endpointBulkIn;      /*!< The endpoint number of the bulk IN pipe */
984     uint8_t endpointBulkOut;     /*!< The endpoint number of the bulk OUT pipe */
985     uint8_t slots;               /*!< The slot number of the application */
986     uint8_t bulkInBusy;          /*!< The bulk IN pipe is busy or not. */
987     uint8_t interruptInBusy;     /*!< The interrupt IN pipe is busy or not. */
988     uint8_t slotsChanged;        /*!< The slot status changed */
989 } usb_device_ccid_struct_t;
990 
991 /*******************************************************************************
992  * API
993  ******************************************************************************/
994 
995 #if defined(__cplusplus)
996 extern "C" {
997 #endif
998 
999 /*!
1000  * @brief Initialize the CCID class.
1001  *
1002  * This function is used to initialize the CCID class. This function only can be called by #USB_DeviceClassInit.
1003  *
1004  * @param[in] controllerId   The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
1005  * @param[in] config          The class configuration information.
1006  * @param[out] handle          An out parameter used to return pointer of the video class handle to the caller.
1007  *
1008  * @return A USB error code or kStatus_USB_Success.
1009  */
1010 extern usb_status_t USB_DeviceCcidInit(uint8_t controllerId,
1011                                        usb_device_class_config_struct_t *config,
1012                                        class_handle_t *handle);
1013 
1014 /*!
1015  * @brief Deinitializes the device CCID class.
1016  *
1017  * The function deinitializes the device CCID class. This function can only be called by #USB_DeviceClassDeinit.
1018  *
1019  * @param[in] handle The CCID class handle received from usb_device_class_config_struct_t::classHandle.
1020  *
1021  * @return A USB error code or kStatus_USB_Success.
1022  */
1023 extern usb_status_t USB_DeviceCcidDeinit(class_handle_t handle);
1024 
1025 /*!
1026  * @brief Handles the event passed to the CCID class.
1027  *
1028  * This function handles the event passed to the CCID class. This function can only be called by #USB_DeviceClassEvent.
1029  *
1030  * @param[in] handle          The CCID class handle, received from the usb_device_class_config_struct_t::classHandle.
1031  * @param[in] event           The event codes. See the enumeration #usb_device_class_event_t.
1032  * @param[in,out] param           The parameter type is determined by the event code.
1033  *
1034  * @return A USB error code or kStatus_USB_Success.
1035  * @retval kStatus_USB_Success              Free device handle successfully.
1036  * @retval kStatus_USB_InvalidParameter     The device handle not be found.
1037  * @retval kStatus_USB_InvalidRequest       The request is invalid and the control pipe is stalled by the caller.
1038  */
1039 extern usb_status_t USB_DeviceCcidEvent(void *handle, uint32_t event, void *param);
1040 
1041 /*!
1042  * @name USB device CCID class APIs
1043  * @{
1044  */
1045 
1046 /*!
1047  * @brief Notifies the slot status changed.
1048  *
1049  * The function is used to notify that the slot status changed. This is a non-blocking function. The event
1050  * kUSB_DeviceCcidEventSlotChangeSent
1051  * is asserted when the transfer completed.
1052  *
1053  * The slot status may not be sent to the host if the interrupt IN pipe is busy. The status is saved internally
1054  * and sent to the host when the interrupt IN pipe callback called. So, the event
1055  * kUSB_DeviceCcidEventSlotChangeSent
1056  * happened times does not equal to the function call times of this function.
1057  *
1058  * @param[in] handle The CCID class handle received from usb_device_class_config_struct_t::classHandle.
1059  * @param[in] slot   The changed slot number.
1060  * @param[in] state  The changed slot status.
1061  *
1062  * @return A USB error code or kStatus_USB_Success.
1063  */
1064 extern usb_status_t USB_DeviceCcidNotifySlotChange(class_handle_t handle,
1065                                                    uint8_t slot,
1066                                                    usb_device_ccid_slot_state_t state);
1067 
1068 /*!
1069  * @brief Notifies the slot status changed.
1070  *
1071  * The function is used to notify the hardware error. This is a non-blocking function. The event
1072  * kUSB_DeviceCcidEventHardwareErrorSent
1073  * is asserted when the transfer completed.
1074  *
1075  * If the interrupt IN pipe is busy, the function returns an error kStatus_USB_Error.
1076  *
1077  * @param[in] handle      The CCID class handle received from usb_device_class_config_struct_t::classHandle.
1078  * @param[in] slot        The changed slot number.
1079  * @param[in] errorCode  The hardware error code.
1080  *
1081  * @return A USB error code or kStatus_USB_Success.
1082  */
1083 extern usb_status_t USB_DeviceCcidNotifyHardwareError(class_handle_t handle,
1084                                                       uint8_t slot,
1085                                                       usb_device_ccid_hardware_error_t errorCode);
1086 
1087 /*! @}*/
1088 
1089 #if defined(__cplusplus)
1090 }
1091 #endif
1092 
1093 /*! @}*/
1094 
1095 #endif /* __USB_DEVICE_CCID_H__ */
1096