1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** USBX Component                                                        */
16 /**                                                                       */
17 /**   Device CCID Class                                                   */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 /**************************************************************************/
23 /*                                                                        */
24 /*  COMPONENT DEFINITION                                   RELEASE        */
25 /*                                                                        */
26 /*    ux_device_class_ccid.h                              PORTABLE C      */
27 /*                                                           6.3.0        */
28 /*  AUTHOR                                                                */
29 /*                                                                        */
30 /*    Chaoqiong Xiao, Microsoft Corporation                               */
31 /*                                                                        */
32 /*  DESCRIPTION                                                           */
33 /*                                                                        */
34 /*    This file defines the equivalences for the USBX Device Class CCID   */
35 /*    (Smart-Card Integrated Circuit(s) Card) component.                  */
36 /*                                                                        */
37 /*  RELEASE HISTORY                                                       */
38 /*                                                                        */
39 /*    DATE              NAME                      DESCRIPTION             */
40 /*                                                                        */
41 /*  04-25-2022     Chaoqiong Xiao           Initial Version 6.1.11        */
42 /*  03-08-2023     Chaoqiong Xiao           Modified comment(s),          */
43 /*                                            added standalone support,   */
44 /*                                            resulting in version 6.2.1  */
45 /*  10-31-2023     Yajun xia, CQ Xiao       Modified comment(s),          */
46 /*                                            added error checks support, */
47 /*                                            resulting in version 6.3.0  */
48 /*                                                                        */
49 /**************************************************************************/
50 
51 #ifndef UX_DEVICE_CLASS_CCID_H
52 #define UX_DEVICE_CLASS_CCID_H
53 
54 /* Determine if a C++ compiler is being used.  If so, ensure that standard
55    C is used to process the API information.  */
56 
57 #ifdef   __cplusplus
58 
59 /* Yes, C++ compiler is present.  Use standard C.  */
60 extern   "C" {
61 #endif
62 
63 /* Internal option: enable the basic USBX error checking. This define is typically used
64    while debugging application.  */
65 #if defined(UX_ENABLE_ERROR_CHECKING) && !defined(UX_DEVICE_CLASS_CCID_ENABLE_ERROR_CHECKING)
66 #define UX_DEVICE_CLASS_CCID_ENABLE_ERROR_CHECKING
67 #endif
68 
69 
70 /* Notification/interrupt endpoint buffer size, must be larger than max packet size in framework, and aligned in 4-bytes.  */
71 #define UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE                          16
72 
73 /* Bulk endpoints buffer size, must be larger than dwMaxCCIDMessageLength and wMaxPacketSize in framework, and aligned in 4-bytes.  */
74 #define UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE                               UX_SLAVE_REQUEST_DATA_MAX_LENGTH
75 
76 
77 #if !defined(UX_DEVICE_STANDALONE)
78 
79 /* Define CCID max number of slots, 32 for 32 bit data width.  */
80 #define UX_DEVICE_CLASS_CCID_MAX_N_SLOTS                                    (4*8)
81 #else
82 
83 /* To optimize the max number of slots fixed to 1.  */
84 #define UX_DEVICE_CLASS_CCID_MAX_N_SLOTS                                    1
85 #endif
86 
87 /* Thread stack size, for RTOS mode only.  */
88 #define UX_DEVICE_CLASS_CCID_THREAD_STACK_SIZE                              UX_THREAD_STACK_SIZE
89 #define UX_DEVICE_CLASS_CCID_NOTIFY_THREAD_STACK_SIZE                       UX_THREAD_STACK_SIZE
90 #define UX_DEVICE_CLASS_CCID_RUNNER_THREAD_STACK_SIZE                       UX_THREAD_STACK_SIZE
91 
92 /* Define CCID Class USB Class constants.  */
93 #define UX_DEVICE_CLASS_CCID_CLASS                                          0x0B
94 
95 #define UX_DEVICE_CLASS_CCID_SUBCLASS                                       0
96 
97 #define UX_DEVICE_CLASS_CCID_PROTOCOL                                       0
98 
99 #define UX_DEVICE_CLASS_CCID_BCD_CCID_1_10                                  0x0110
100 
101 #define UX_DEVICE_CLASS_CCID_VOLTAGE_SUPPORT_5_0                            1u
102 #define UX_DEVICE_CLASS_CCID_VOLTAGE_SUPPORT_3_0                            2u
103 #define UX_DEVICE_CLASS_CCID_VOLTAGE_SUPPORT_1_8                            4u
104 
105 #define UX_DEVICE_CLASS_CCID_PROTOCOLS_T0                                   1u
106 #define UX_DEVICE_CLASS_CCID_PROTOCOLS_T1                                   2u
107 
108 #define UX_DEVICE_CLASS_CCID_SYNCH_PROTOCOLS_2_WIRE                         1u
109 #define UX_DEVICE_CLASS_CCID_SYNCH_PROTOCOLS_3_WIRE                         2u
110 #define UX_DEVICE_CLASS_CCID_SYNCH_PROTOCOLS_I2C                            4u
111 
112 #define UX_DEVICE_CLASS_CCID_MECHANICAL_NO_SPECIAL                          0u
113 #define UX_DEVICE_CLASS_CCID_MECHANICAL_ACCEPT                              1u
114 #define UX_DEVICE_CLASS_CCID_MECHANICAL_EJECT                               2u
115 #define UX_DEVICE_CLASS_CCID_MECHANICAL_CAPTURE                             4u
116 #define UX_DEVICE_CLASS_CCID_MECHANICAL_LOCK_UNLOCK                         8u
117 
118 #define UX_DEVICE_CLASS_CCID_FEATURES_NO_SPECIAL                            0u
119 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_PARAMETER_ATR                    2u
120 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_ACTIVATION                       4u
121 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_VOLTAGE                          8u
122 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_CLOCK_FREQUENCY                  0x10u
123 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_BAUD_RATE                        0x20u
124 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_PARAMETER_NEGOTIATION            0x40u
125 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_PPS                              0x80u
126 #define UX_DEVICE_CLASS_CCID_FEATURES_CAN_SET_ICC_IN_CLOCK_STOP             0x100u
127 #define UX_DEVICE_CLASS_CCID_FEATURES_NAD_NOT_0_ACCEPTED                    0x200u
128 #define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_IFSD_EXCHANGE_1ST                0x400u
129 #define UX_DEVICE_CLASS_CCID_FEATURES_TPUD_EXCHANGES                        0x10000u
130 #define UX_DEVICE_CLASS_CCID_FEATURES_SHORT_APUD_EXCHANGES                  0x20000u
131 #define UX_DEVICE_CLASS_CCID_FEATURES_SHORT_AND_EXTENDED_APUD_EXCHANGES     0x40000u
132 #define UX_DEVICE_CLASS_CCID_FEATURES_WAKEUP_ON_INSERTION_REMOVAL           0x100000u
133 
134 #define UX_DEVICE_CLASS_CCID_LCD_LAYOUT_NO_LCD                              0
135 #define UX_DEVICE_CLASS_CCID_LCD_LAYOUT(n_lines,n_per_line)                 (((n_lines) << 8) | (n_per_line))
136 
137 #define UX_DEVICE_CLASS_CCID_PIN_SUPPORT_VERIFICATION                       1u
138 #define UX_DEVICE_CLASS_CCID_PIN_SUPPORT_MODIFICATION                       2u
139 
140 #define UX_DEVICE_CLASS_CCID_MAX_CCID_MESSAGE_EXT_APDU_MIN                  (261+10)
141 #define UX_DEVICE_CLASS_CCID_MAX_CCID_MESSAGE_EXT_APDU_MAX                  (65544+10)
142 
143 
144 /* Device CCID Requests */
145 #define UX_DEVICE_CLASS_CCID_ABORT                                          0x01
146 #define UX_DEVICE_CLASS_CCID_GET_CLOCK_FREQUENCIES                          0x02
147 #define UX_DEVICE_CLASS_CCID_GET_DATA_RATES                                 0x03
148 
149 
150 /* CCID message offsets, values.  */
151 
152 /* General.  */
153 #define UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH                          10
154 
155 #define UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE                            0
156 #define UX_DEVICE_CLASS_CCID_OFFSET_LENGTH                                  1
157 #define UX_DEVICE_CLASS_CCID_OFFSET_SLOT                                    5
158 #define UX_DEVICE_CLASS_CCID_OFFSET_SEQ                                     6
159 
160 #define UX_DEVICE_CLASS_CCID_OFFSET_DATA                                    10
161 
162 /* PC_to_RDR_IccPowerOn.  */
163 #define UX_DEVICE_CLASS_CCID_OFFSET_POWER_SELECT                            7
164 #define UX_DEVICE_CLASS_CCID_POWER_SELECT_AUTO                              0
165 #define UX_DEVICE_CLASS_CCID_POWER_SELECT_5_0_V                             1
166 #define UX_DEVICE_CLASS_CCID_POWER_SELECT_3_0_V                             2
167 #define UX_DEVICE_CLASS_CCID_POWER_SELECT_1_8_V                             3
168 
169 /* PC_to_RDR_XfrBlock/PC_to_RDR_Secure.  */
170 #define UX_DEVICE_CLASS_CCID_OFFSET_BWI                                     7
171 #define UX_DEVICE_CLASS_CCID_OFFSET_LEVEL_PARAMETER                         8
172 #define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_RFU                            0x00u
173 #define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_BEGIN_END                      0x00u
174 #define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_BEGIN_CONTINUE                 0x01u
175 #define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_CONTINUE_END                   0x02u
176 #define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_CONTINUE                       0x03u
177 #define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_EMPTY_DATA                     0x10u
178 
179 /* PC_to_RDR_SetParameters.  */
180 #define UX_DEVICE_CLASS_CCID_OFFSET_SET_PARAMETERS_PROTOCOL_NUM             7
181 
182 #define UX_DEVICE_CLASS_CCID_PROTOCOL_T_0                                   0
183 #define UX_DEVICE_CLASS_CCID_PROTOCOL_T_1                                   1
184 #define UX_DEVICE_CLASS_CCID_PROTOCOL_2_WIRE                                0x80
185 #define UX_DEVICE_CLASS_CCID_PROTOCOL_3_WIRE                                0x81
186 #define UX_DEVICE_CLASS_CCID_PROTOCOL_I2C                                   0x82
187 
188 /* Parameters.  */
189 #define UX_DEVICE_CLASS_CCID_OFFSET_FI_DI                                   10
190 
191 #define UX_DEVICE_CLASS_CCID_OFFSET_TCCKS_T0                                11
192 #define UX_DEVICE_CLASS_CCID_OFFSET_GUARD_TIME_T0                           12
193 #define UX_DEVICE_CLASS_CCID_OFFSET_WAITING_INTEGER_T0                      13
194 #define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_STOP_T0                           14
195 
196 #define UX_DEVICE_CLASS_CCID_OFFSET_TCCKS_T1                                11
197 #define UX_DEVICE_CLASS_CCID_OFFSET_GUARD_TIME_T1                           12
198 #define UX_DEVICE_CLASS_CCID_OFFSET_WAITING_INTEGERS_T1                     13
199 #define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_STOP_T1                           14
200 #define UX_DEVICE_CLASS_CCID_OFFSET_IFSC                                    15
201 #define UX_DEVICE_CLASS_CCID_OFFSET_NAD_VALUE                               16
202 
203 /* PC_to_RDR_IccClock.  */
204 #define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_COMMAND                           7
205 #define UX_DEVICE_CLASS_CCID_CLOCK_COMMAND_RESTART                          0
206 #define UX_DEVICE_CLASS_CCID_CLOCK_COMMAND_STOP                             1
207 
208 /* PC_to_RDR_T0APDU.  */
209 #define UX_DEVICE_CLASS_CCID_OFFSET_CHANGES                                 7
210 #define UX_DEVICE_CLASS_CCID_OFFSET_CLASS_GET_RESPONSE                      8
211 #define UX_DEVICE_CLASS_CCID_OFFSET_CLASS_ENVELOPE                          9
212 #define UX_DEVICE_CLASS_CCID_CHANGE_CLASS_GET_RESPONSE                      (1u << 0)
213 #define UX_DEVICE_CLASS_CCID_CHANGE_CLASS_ENVELOPE                          (1u << 1)
214 
215 /* PC_to_RDR_Secure.  */
216 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_OPERATION                           10
217 #define UX_DEVICE_CLASS_CCID_PIN_VERIFICATION                               0
218 #define UX_DEVICE_CLASS_CCID_PIN_MODIFICATION                               1
219 #define UX_DEVICE_CLASS_CCID_PIN_TRANSFER                                   2
220 #define UX_DEVICE_CLASS_CCID_PIN_WAIT_ICC_RESP                              3
221 #define UX_DEVICE_CLASS_CCID_PIN_CANCEL                                     4
222 #define UX_DEVICE_CLASS_CCID_PIN_RESEND_I_BLOCK                             5
223 #define UX_DEVICE_CLASS_CCID_PIN_NEXT_APDU                                  6
224 
225 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_DATA                                11
226 
227 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_TIME_OUT                            11
228 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_FORMAT_STRING                       12
229 
230 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_FORMAT_TYPE_MASK                 (0x3u << 0)
231 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_BINARY                           (0x0u << 0)
232 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_BCD                              (0x1u << 0)
233 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_ASCII                            (0x2u << 0)
234 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_JUSTIFICATION                    (0x1u << 2)
235 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_LEFT_JUSTIFY                     (0x0u << 2)
236 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_RIGHT_JUSTIFY                    (0x1u << 2)
237 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_POSITION_MASK                    (0xFu << 3)
238 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_POSITION(v)                      (((v) >> 3) & 0xFu)
239 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_UNIT_TYPE                        (0x1u << 7)
240 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_UNIT_BITS                        (0x0u << 7)
241 #define UX_DEVICE_CLASS_CCID_FORMAT_STRING_UNIT_BYTES                       (0x1u << 7)
242 
243 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_PIN_BLOCK_STRING                    13
244 #define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_LENGTH_BITS_MASK          (0xFu << 3)
245 #define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_BLOCK_SIZE_BYTES_MASK     (0xFu << 0)
246 #define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_LENGTH_BITS(v)            ((v) >> 4) & 0xFu)
247 #define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_BLOCK_SIZE_BYTES(v)       ((v) >> 0) & 0xFu)
248 
249 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_PIN_LENGTH_FORMAT                   14
250 #define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_UNIT_TYPE                    (1u << 4)
251 #define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_UNIT_BITS                    (0u << 4)
252 #define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_UNIT_BYTES                   (1u << 4)
253 #define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_POSITION_MASK                (0xFu << 0)
254 #define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_POSITION(v)                  (((v) << 0) & 0xFu)
255 
256 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_TIME_OUT                     11
257 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_FORMAT_STRING                12
258 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_BLOCK_STRING             13
259 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_LENGTH_FORMAT            14
260 
261 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_MAX_EXTRA_DIGIT          15
262 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_MAX_EXTRA_DIGIT_MIN      16
263 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_MAX_EXTRA_DIGIT_MAX      15
264 
265 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_ENTRY_VALIDATION_CONDITION   17
266 #define UX_DEVICE_CLASS_CCID_PIN_ENTRY_VALIDATION_MAX_SIZE                  1u
267 #define UX_DEVICE_CLASS_CCID_PIN_ENTRY_VALIDATION_KEY_PRESS                 2u
268 #define UX_DEVICE_CLASS_CCID_PIN_ENTRY_VALIDATION_TIMEOUT                   4u
269 
270 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_NUMBER_MESSAGE               18
271 #define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_NO                          0
272 #define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_1                           0
273 #define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_2                           0
274 #define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_3                           0
275 #define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_DEFAULT                     0xFF
276 
277 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_LANG_ID                      19
278 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_MSG_INDEX                    21
279 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_TEO_PROLOGUE                 22
280 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_APDU                     25
281 
282 #define UX_DEVICE_CLASS_CCID_PIN_MESSAGE_INSERT_PROMPT                      0
283 #define UX_DEVICE_CLASS_CCID_PIN_MESSAGE_MODIFY_PROMPT                      1
284 #define UX_DEVICE_CLASS_CCID_PIN_MESSAGE_NEW_CONFIRM_PROMPT                 2
285 
286 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TIME_OUT                     11
287 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_FORMAT_STRING                12
288 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_BLOCK_STRING             13
289 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_LENGTH_FORMAT            14
290 
291 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_INSERTION_OFFSET_OLD         15
292 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_INSERTION_OFFSET_NEW         16
293 
294 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_MAX_EXTRA_DIGIT          17
295 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_MAX_EXTRA_DIGIT_MIN      18
296 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_MAX_EXTRA_DIGIT_MAX      17
297 
298 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_CONFIRM_PIN                  19
299 #define UX_DEVICE_CLASS_CCID_CONFIRM_PIN_CONFIRM_REQUESTED                  (1u << 0)
300 #define UX_DEVICE_CLASS_CCID_CONFIRM_PIN_ENTRY_REQUESTED                    (1u << 1)
301 
302 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_ENTRY_VALIDATION_CONDITION   20
303 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_NUMBER_MESSAGE               21
304 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_LANG_ID                      22
305 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_MSG_INDEX1                   24
306 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_MSG_INDEX2                   25
307 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_MSG_INDEX3                   26
308 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TEO_PROLOGUE1                25
309 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TEO_PROLOGUE2                26
310 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TEO_PROLOGUE3                27
311 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_APDU1                    28
312 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_APDU2                    29
313 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_APDU3                    30
314 
315 #define UX_DEVICE_CLASS_CCID_OFFSET_PIN_NEXT_APDU_TEO_PROLOGUE              11
316 
317 /* PC_to_RDR_Mechanical.  */
318 #define UX_DEVICE_CLASS_CCID_OFFSET_FUNCTION                                7
319 #define UX_DEVICE_CLASS_CCID_FUNCTION_ACCEPT_CARD                           0x01
320 #define UX_DEVICE_CLASS_CCID_FUNCTION_EJECT_CARD                            0x02
321 #define UX_DEVICE_CLASS_CCID_FUNCTION_CAPTURE_CARD                          0x03
322 #define UX_DEVICE_CLASS_CCID_FUNCTION_LOCK_CARD                             0x04
323 #define UX_DEVICE_CLASS_CCID_FUNCTION_UNLOCK_CARD                           0x05
324 
325 /* PC_to_RDR_SetDataRateAndClockFrequency/RDR_to_PC_DataRateAndClockFrequency.  */
326 #define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_FREQUENCY                         10
327 #define UX_DEVICE_CLASS_CCID_OFFSET_DATA_RATE                               14
328 
329 /* RDR_to_PC_   */
330 #define UX_DEVICE_CLASS_CCID_OFFSET_STATUS                                  7
331 #define UX_DEVICE_CLASS_CCID_OFFSET_ERROR                                   8
332 
333 /* RDR_to_PC_DataBlock.  */
334 #define UX_DEVICE_CLASS_CCID_OFFSET_CHAIN_PARAMETER                         9
335 #define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_BEGIN_END                      0x00
336 #define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_BEGIN_CONTINUE                 0x01
337 #define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_CONTINUE_END                   0x02
338 #define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_CONTINUE                       0x03
339 #define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_EMPTY                          0x10
340 
341 /* RDR_to_PC_SlotStatus.  */
342 #define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_STATUS                            9
343 
344 /* RDR_to_PC_Parameters.  */
345 #define UX_DEVICE_CLASS_CCID_OFFSET_PARAMETERS_PROTOCOL_NUM                 9
346 
347 #define UX_DEVICE_CLASS_CCID_PARAMETERS_T0_LENGTH                           5
348 #define UX_DEVICE_CLASS_CCID_PARAMETERS_T1_LENGTH                           7
349 
350 /* RDR_to_PC_NotifySlotChange.  */
351 #define UX_DEVICE_CLASS_CCID_OFFSET_SLOT_ICC_STATE                          1
352 
353 /* RDR_to_PC_HardwareError.  */
354 #define UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SLOT                           1
355 #define UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SEQ                            2
356 #define UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_CODE                           3
357 #define UX_DEVICE_CLASS_CCID_HW_ERROR_OVERCURRENT                           1
358 
359 
360 /* CCID bMessageTypes.  */
361 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON                         0x62
362 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_OFF                        0x63
363 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_SLOT_STATUS                      0x64
364 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK                            0x6F
365 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_PARAMETERS                       0x6C
366 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_RESET_PARAMETERS                     0x6D
367 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS                       0x61
368 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ESCAPE                               0x6B
369 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK                            0x6E
370 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU                              0x6A
371 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE                               0x69
372 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL                           0x71
373 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT                                0x72
374 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQ         0x73
375 
376 #define UX_DEVICE_CLASS_CCID_N_COMMANDS                                     14
377 
378 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK                           0x80
379 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS                          0x81
380 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS                           0x82
381 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_ESCAPE                               0x83
382 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQ             0x84
383 
384 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_NOTIFY_SLOT_CHANGE                   0x50
385 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_HARDWARE_ERROR                       0x51
386 
387 #define UX_DEVICE_CLASS_CCID_COMMAND_ABORTABLE(bMessageType)                \
388     (((bMessageType) == 0x62) || ((bMessageType) == 0x6F) ||                \
389      ((bMessageType) == 0x6B) || ((bMessageType) == 0x69) ||                \
390      ((bMessageType) == 0x71) || ((bMessageType) == 0x72))
391 
392 #define UX_DEVICE_CLASS_CCID_COMMAND_HW_ERROR_CHECK(bMessageType)           \
393     (((bMessageType) != 0x63) && ((bMessageType) != 0x6B) &&                \
394      ((bMessageType) != 0x6A) && ((bMessageType) != 0x72) &&                \
395      ((bMessageType) != 0x73))
396 
397 #define UX_DEVICE_CLASS_CCID_COMMAND_AUTO_SEQUENCE_CHECK(bMessageType)      \
398     (((bMessageType) != 0x62) && ((bMessageType) != 0x65) &&                \
399      ((bMessageType) != 0x6B) && ((bMessageType) != 0x6A) &&                \
400      ((bMessageType) != 0x72) && ((bMessageType) != 0x73))
401 
402 #define UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_BLOCK(m)                     \
403     ((m) == 0x62 || (m) == 0x6F || (m) == 0x69)
404 #define UX_DEVICE_CLASS_CCID_COMMAND_RESP_SLOT_STATUS(m)                    \
405     ((m) == 0x63 || (m) == 0x64 || (m) == 0x6E || (m) == 0x6A ||            \
406      (m) == 0x71 || (m) == 0x72 || (m) == 0x65)
407 #define UX_DEVICE_CLASS_CCID_COMMAND_RESP_PARAMETERS(m)                     \
408     ((m) == 0x6C || (m) == 0x6D || (m) == 0x61)
409 #define UX_DEVICE_CLASS_CCID_COMMAND_RESP_ESCAPE(m)                         \
410     ((m) == 0x6B)
411 #define UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_RATE_AND_CLOCK_FREQ(m)       \
412     ((m) == 0x73)
413 
414 #define UX_DEVICE_CLASS_CCID_COMMAND_RESP_TYPE(m)                           \
415     (UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_BLOCK(m) ? 0x80 :               \
416      UX_DEVICE_CLASS_CCID_COMMAND_RESP_SLOT_STATUS(m) ? 0x81 :              \
417      UX_DEVICE_CLASS_CCID_COMMAND_RESP_PARAMETERS(m) ? 0x82 :               \
418      UX_DEVICE_CLASS_CCID_COMMAND_RESP_ESCAPE(m) ? 0x83 :                   \
419      UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_RATE_AND_CLOCK_FREQ(m) ? 0x84 : \
420      0)
421 
422 /* CCID Slot error binary code.  */
423 #define UX_DEVICE_CLASS_CCID_CMD_ABORTED                                    0xFF
424 #define UX_DEVICE_CLASS_CCID_ICC_MUTE                                       0xFE
425 #define UX_DEVICE_CLASS_CCID_XFR_PARITY_ERROR                               0xFD
426 #define UX_DEVICE_CLASS_CCID_XFR_OVERRUN                                    0xFC
427 #define UX_DEVICE_CLASS_CCID_HW_ERROR                                       0xFB
428 #define UX_DEVICE_CLASS_CCID_BAD_ATR_TS                                     0xF8
429 #define UX_DEVICE_CLASS_CCID_BAD_ATR_TCK                                    0xF7
430 #define UX_DEVICE_CLASS_CCID_ICC_PROTOCOL_NOT_SUPPORTED                     0xF6
431 #define UX_DEVICE_CLASS_CCID_ICC_CLASS_NOT_SUPPORTED                        0xF5
432 #define UX_DEVICE_CLASS_CCID_PROCEDURE_BYTE_CONFLICT                        0xF4
433 #define UX_DEVICE_CLASS_CCID_DEACTIVATED_PROTOCOL                           0xF3
434 #define UX_DEVICE_CLASS_CCID_BUSY_WITH_AUTO_SEQUENCE                        0xF2
435 #define UX_DEVICE_CLASS_CCID_PIN_TIMEOUT                                    0xF0
436 #define UX_DEVICE_CLASS_CCID_PIN_CANCELLED                                  0xEF
437 #define UX_DEVICE_CLASS_CCID_CMD_SLOT_BUSY                                  0xE0
438 
439 
440 /* CCID bStatus.  */
441 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_TIME_EXTENSION                     0x80
442 
443 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_ACTIVE                         (0x0u)
444 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_INACTIVE                       (0x1u)
445 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_NOT_PRESENT                    (0x2u)
446 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_MASK                           (0x3u)
447 
448 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_NO_ERROR                       (0x0u << 6)
449 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_FAILED                         (0x1u << 6)
450 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_TIME_EXTENSION                 (0x2u << 6)
451 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_MASK                           (0x3u << 6)
452 
453 #define UX_DEVICE_CLASS_CCID_SLOT_STATUS(bmICCStatus, bmCommandStatus)      ((bmICCStatus) | ((bmCommandStatus) << 6))
454 #define UX_DEVICE_CLASS_CCID_ICC_ACTIVE                                     0
455 #define UX_DEVICE_CLASS_CCID_ICC_INACTIVE                                   1
456 #define UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT                                2
457 #define UX_DEVICE_CLASS_CCID_CMD_NO_ERROR                                   0
458 #define UX_DEVICE_CLASS_CCID_CMD_FAILED                                     1
459 #define UX_DEVICE_CLASS_CCID_CMD_TIME_EXTENSION                             2
460 
461 
462 /* CCID events.  */
463 #define UX_DEVICE_CLASS_CCID_EVENT_SLOT(n)                                  (1u<<(n))
464 
465 
466 /* CCID flags.  */
467 #define UX_DEVICE_CLASS_CCID_FLAG_ABORTABLE                                 0x80u
468 #define UX_DEVICE_CLASS_CCID_FLAG_BUSY                                      0x40u
469 
470 #define UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE                             0x01u
471 #define UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_HW_ERROR                           0x02u
472 
473 #define UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING                           0x04u
474 #define UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR                                  0x08u
475 
476 
477 #define UX_DEVICE_CLASS_CCID_COMMAND_FLAG_ABORTABLE(bMessageType)           \
478     (UX_DEVICE_CLASS_CCID_COMMAND_ABORTABLE(bMessageType) ?                 \
479      UX_DEVICE_CLASS_CCID_FLAG_ABORTABLE : 0)
480 
481 #define UX_DEVICE_CLASS_CCID_COMMAND_FLAG_AUTO_SEQUENCE_CHECK(bMessageType) \
482     (UX_DEVICE_CLASS_CCID_COMMAND_AUTO_SEQUENCE_CHECK(bMessageType) ?       \
483      UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING : 0)
484 
485 #define UX_DEVICE_CLASS_CCID_COMMAND_FLAG_HW_ERROR_CHECK(bMessageType)      \
486     (UX_DEVICE_CLASS_CCID_COMMAND_HW_ERROR_CHECK(bMessageType) ?            \
487      UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR : 0)
488 
489 #define UX_DEVICE_CLASS_CCID_COMMAND_FLAGS(bMessageType)                    \
490     (UX_DEVICE_CLASS_CCID_COMMAND_FLAG_ABORTABLE(bMessageType) |            \
491      UX_DEVICE_CLASS_CCID_COMMAND_FLAG_AUTO_SEQUENCE_CHECK(bMessageType) |  \
492      UX_DEVICE_CLASS_CCID_COMMAND_FLAG_HW_ERROR_CHECK(bMessageType))
493 
494 
495 /* CCID message structures.  */
496 
497 /* General message for both PC_to_RDR and RDR_to_PC.  */
498 typedef struct UX_DEVICE_CLASS_CCID_MESSAGES_STRUCT
499 {
500     UCHAR       *ux_device_class_ccid_messages_pc_to_rdr;
501     UCHAR       *ux_device_class_ccid_messages_rdr_to_pc;
502     ULONG       ux_device_class_ccid_messages_rdr_to_pc_length; /* Total buffer length including header.  */
503 } UX_DEVICE_CLASS_CCID_MESSAGES;
504 
505 /* Define CCID message header.  */
506 typedef struct UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_STRUCT
507 {
508     UCHAR       bMessageType;
509     UCHAR       dwLength[4];
510     UCHAR       bSlot;
511     UCHAR       bSeq;
512     UCHAR       bRFU[3];
513 } UX_DEVICE_CLASS_CCID_MESSAGE_HEADER;
514 #define UX_DEVICE_CLASS_CCID_MESSAGE_TYPE(msg)                      (((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->bMessageType)
515 #define UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_GET(msg)                _ux_utility_long_get(((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->dwLength)
516 #define UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(msg,len)            _ux_utility_long_put(((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->dwLength, (len))
517 #define UX_DEVICE_CLASS_CCID_MESSAGE_SLOT(msg)                      (((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->bSlot)
518 #define UX_DEVICE_CLASS_CCID_MESSAGE_SEQ(msg)                       (((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->bSeq)
519 #define UX_DEVICE_CLASS_CCID_MESSAGE_DATA(msg)                      (((UCHAR *)(msg) + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH))
520 
521 /* Define CCID PC_to_RDR_IccPowerOn.  */
522 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER_STRUCT
523 {
524     UCHAR       bMessageType;
525     UCHAR       dwLength[4];
526     UCHAR       bSlot;
527     UCHAR       bSeq;
528     UCHAR       bPowerSelect;
529     UCHAR       bRFU[2];
530 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER;
531 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_POWER_SELECT(msg)            (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER*)(msg))->bPowerSelect)
532 
533 /* Define CCID PC_to_RDR_IccPowerOff.  */
534 typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_OFF_HEADER;
535 
536 /* Define CCID PC_to_RDR_GetSlotStatus.  */
537 typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_SLOT_STATUS_HEADER;
538 
539 /* Define CCID PC_to_RDR_XfrBlock.  */
540 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER_STRUCT
541 {
542     UCHAR       bMessageType;
543     UCHAR       dwLength[4];
544     UCHAR       bSlot;
545     UCHAR       bSeq;
546     UCHAR       bBWI;
547     USHORT      wLevelParameter;
548 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER;
549 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_BWI(msg)                     (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER*)(msg))->bBWI)
550 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_LEVEL_PARAMETER(msg)         (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER*)(msg))->wLevelParameter)
551 
552 /* Define CCID PC_to_RDR_GetParameters.  */
553 typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_PARAMETERS_HEADER;
554 
555 /* Define CCID PC_to_RDR_ResetParameters.  */
556 typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_RESET_PARAMETERS_HEADER;
557 
558 /* Define CCID PC_to_RDR_SetParameters.  */
559 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER_STRUCT
560 {
561     UCHAR       bMessageType;
562     UCHAR       dwLength[4];
563     UCHAR       bSlot;
564     UCHAR       bSeq;
565     UCHAR       bProtocolNum;
566     UCHAR       bRFU[2];
567 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER;
568 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PROTOCOL_NUM(msg)            (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER*)(msg))->bProtocolNum)
569 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0_STRUCT
570 {
571     UCHAR       bMessageType;
572     UCHAR       dwLength[4];
573     UCHAR       bSlot;
574     UCHAR       bSeq;
575     UCHAR       bProtocolNum;
576     UCHAR       bRFU[2];
577     UCHAR       bmFindexDindex;
578     UCHAR       bmTCCKST0;
579     UCHAR       bGuardTimeT0;
580     UCHAR       bWaitingIntegerT0;
581     UCHAR       bClockStop;
582 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0;
583 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0_LENGTH     5
584 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1_STRUCT
585 {
586     UCHAR       bMessageType;
587     UCHAR       dwLength[4];
588     UCHAR       bSlot;
589     UCHAR       bSeq;
590     UCHAR       bProtocolNum;
591     UCHAR       bRFU[2];
592     UCHAR       bmFindexDindex;
593     UCHAR       bmTCCKST1;
594     UCHAR       bGuardTimeT1;
595     UCHAR       bmWaitingIntegersT1;
596     UCHAR       bClockStop;
597     UCHAR       bIFSC;
598     UCHAR       bNadValue;
599 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1;
600 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1_LENGTH     7
601 
602 /* Define CCID PC_to_RDR_Escape.  */
603 typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_ESCAPE_HEADER;
604 
605 /* Define CCID PC_to_RDR_IccClock.  */
606 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER_STRUCT
607 {
608     UCHAR       bMessageType;
609     UCHAR       dwLength[4];
610     UCHAR       bSlot;
611     UCHAR       bSeq;
612     UCHAR       bClockCommand;
613     UCHAR       bRFU[2];
614 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER;
615 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_CLOCK_COMMAND(msg)           (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER*)(msg))->bClockCommand)
616 
617 /* Define CCID PC_to_RDR_T0APDU.  */
618 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER_STRUCT
619 {
620     UCHAR       bMessageType;
621     UCHAR       dwLength[4];
622     UCHAR       bSlot;
623     UCHAR       bSeq;
624     UCHAR       bmChanges;
625     UCHAR       bClassGetResponse;
626     UCHAR       bClassEnvelope;
627 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER;
628 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_CHANGES(msg)         (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER*)(msg))->bmChanges)
629 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_CLASS_GET_RESP(msg)  (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER*)(msg))->bClassGetResponse)
630 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_CLASS_ENVELOPE(msg)  (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER*)(msg))->bClassEnvelope)
631 
632 /* Define CCID PC_to_RDR_Secure.  */
633 typedef UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_HEADER;
634 
635 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER_STRUCT
636 {
637     UCHAR       bMessageType;
638     UCHAR       dwLength[4];
639     UCHAR       bSlot;
640     UCHAR       bSeq;
641     UCHAR       bBWI;
642     USHORT      wLevelParameter;
643     UCHAR       bPINOperation;
644 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER;
645 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_BWI(msg)                 (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER*)(msg))->bBWI)
646 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_LEVEL_PARAMETER(msg)     (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER*)(msg))->wLevelParameter)
647 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_OPERATION(msg)           (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER*)(msg))->bPINOperation)
648 
649 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_STRUCT
650 {
651     UCHAR       bMessageType;
652     UCHAR       dwLength[4];
653     UCHAR       bSlot;
654     UCHAR       bSeq;
655     UCHAR       bBWI;
656     USHORT      wLevelParameter;
657     UCHAR       bPINOperation;
658 
659     UCHAR       bTimeOut;
660     UCHAR       bmFormatString;
661     UCHAR       bmPINBlockString;
662     UCHAR       bmPINLengthFormat;
663 
664     UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
665     UCHAR       bEntryValidationCondition;
666     UCHAR       bNumberMessage;
667     UCHAR       wLangId[2];
668     UCHAR       bMsgIndex;
669     UCHAR       bTeoPrologue[3];
670 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION;
671 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_TIMEOUT(msg)             (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bTimeOut)
672 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_FORMAT_STRING(msg)       (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bmFormatString)
673 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_BLOCK_STRING(msg)        (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bmPINBlockString)
674 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_LENGTH_FORMAT(msg)       (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bmPINLengthFormat)
675 
676 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_PIN_MAX_EXTRA_DIGIT(msg)            _ux_utility_short_get(((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->wPINMaxExtraDigit)
677 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_PIN_MIN_PIN_SIZE(msg)               (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->wPINMaxExtraDigit[1])
678 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_PIN_MAX_PIN_SIZE(msg)               (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->wPINMaxExtraDigit[0])
679 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_ENTRY_VALIDATION_CONDITION(msg)     (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->bEntryValidationCondition)
680 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_NUMBER_MESSAGE(msg)                 (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->bNumberMessage)
681 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_LANG_ID(msg)                        _ux_utility_short_get(((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->wLangId)
682 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_MESSAGE_INDEX(msg)                  (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->bMsgIndex)
683 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_TEO_PROLOGUE(msg)                   (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_PIN_VERIFICATION*)(msg))->bTeoPrologue)
684 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_DATA(msg)                           ((UCHAR*)(msg) + 25)
685 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_APDU(msg)                           ((UCHAR*)(msg) + 25)
686 
687 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION_STRUCT
688 {
689     UCHAR       bMessageType;
690     UCHAR       dwLength[4];
691     UCHAR       bSlot;
692     UCHAR       bSeq;
693     UCHAR       bBWI;
694     USHORT      wLevelParameter;
695     UCHAR       bPINOperation;
696 
697     UCHAR       bTimeOut;
698     UCHAR       bmFormatString;
699     UCHAR       bmPINBlockString;
700     UCHAR       bmPINLengthFormat;
701 
702     UCHAR       bInsertionOffsetOld;
703     UCHAR       bInsertionOffsetNew;
704     UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
705     UCHAR       bConfirmPIN;
706     UCHAR       bEntryValidationCondition;
707     UCHAR       bNumberMessage;
708     UCHAR       wLangId[2];
709     UCHAR       bMsgIndex1;
710     UCHAR       bTeoPrologue[3];
711 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION;
712 typedef UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1;
713 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1_TEO_PROLOGUE(msg)   ((UCHAR*)(msg) + 25)
714 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1_DATA(msg)           ((UCHAR*)(msg) + 28)
715 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1_APDU(msg)           ((UCHAR*)(msg) + 28)
716 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_STRUCT
717 {
718     UCHAR       bMessageType;
719     UCHAR       dwLength[4];
720     UCHAR       bSlot;
721     UCHAR       bSeq;
722     UCHAR       bBWI;
723     USHORT      wLevelParameter;
724     UCHAR       bPINOperation;
725     UCHAR       bTimeOut;
726     UCHAR       bmFormatString;
727     UCHAR       bmPINBlockString;
728     UCHAR       bmPINLengthFormat;
729     UCHAR       bInsertionOffsetOld;
730     UCHAR       bInsertionOffsetNew;
731     UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
732     UCHAR       bConfirmPIN;
733     UCHAR       bEntryValidationCondition;
734     UCHAR       bNumberMessage;
735     UCHAR       wLangId[2];
736     UCHAR       bMsgIndex1;
737     UCHAR       bMsgIndex2;
738     UCHAR       bTeoPrologue[3];
739 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2;
740 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_TEO_PROLOGUE(msg)   ((UCHAR*)(msg) + 26)
741 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_DATA(msg)           ((UCHAR*)(msg) + 29)
742 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_APDU(msg)           ((UCHAR*)(msg) + 29)
743 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_STRUCT
744 {
745     UCHAR       bMessageType;
746     UCHAR       dwLength[4];
747     UCHAR       bSlot;
748     UCHAR       bSeq;
749     UCHAR       bBWI;
750     USHORT      wLevelParameter;
751     UCHAR       bPINOperation;
752     UCHAR       bTimeOut;
753     UCHAR       bmFormatString;
754     UCHAR       bmPINBlockString;
755     UCHAR       bmPINLengthFormat;
756     UCHAR       bInsertionOffsetOld;
757     UCHAR       bInsertionOffsetNew;
758     UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
759     UCHAR       bConfirmPIN;
760     UCHAR       bEntryValidationCondition;
761     UCHAR       bNumberMessage;
762     UCHAR       wLangId[2];
763     UCHAR       bMsgIndex1;
764     UCHAR       bMsgIndex2;
765     UCHAR       bMsgIndex3;
766     UCHAR       bTeoPrologue[3];
767 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3;
768 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_TEO_PROLOGUE(msg)   ((UCHAR*)(msg) + 27)
769 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_DATA(msg)           ((UCHAR*)(msg) + 30)
770 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_APDU(msg)           ((UCHAR*)(msg) + 30)
771 
772 
773 /* Define CCID PC_to_RDR_Mechanical.  */
774 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER_STRUCT
775 {
776     UCHAR       bMessageType;
777     UCHAR       dwLength[4];
778     UCHAR       bSlot;
779     UCHAR       bSeq;
780     UCHAR       bFunction;
781     UCHAR       bRFU[2];
782 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER;
783 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_FUNCTION(msg)     (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER*)(msg))->bFunction)
784 
785 /* Define CCID PC_to_RDR_Abort.  */
786 typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT_HEADER;
787 
788 /* Define CCID PC_to_RDR_SetDataRateAndClockFrequency.  */
789 typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY_HEADER;
790 typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY_STRUCT
791 {
792     UCHAR       bMessageType;
793     UCHAR       dwLength[4];
794     UCHAR       bSlot;
795     UCHAR       bSeq;
796     UCHAR       bRFU[3];
797     UCHAR       dwClockFrequency[4];
798     UCHAR       dwDataRate[4];
799 } UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY;
800 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_CLOCK_FREQUENCY_GET(msg)     _ux_utility_long_get(((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY*)(msg))->dwClockFrequency)
801 #define UX_DEVICE_CLASS_CCID_PC_TO_RDR_DATA_RATE_GET(msg)           _ux_utility_long_get(((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY*)(msg))->dwDataRate)
802 
803 /* Define CCID RDR_to_PC_ header.  */
804 typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER_STRUCT
805 {
806     UCHAR       bMessageType;
807     UCHAR       dwLength[4];
808     UCHAR       bSlot;
809     UCHAR       bSeq;
810     UCHAR       bStatus;
811     UCHAR       bError;
812     UCHAR       bRFU;
813 } UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER;
814 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_STATUS(msg)                  (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER*)(msg))->bStatus)
815 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_ERROR(msg)                   (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER*)(msg))->bError)
816 
817 /* Define CCID Slot Status Register.  */
818 typedef struct UX_DEVICE_CLASS_CCID_SLOT_STATUS_REGISTER_BITMAP_STRUCT
819 {
820     UCHAR bmICCStatus:2;
821     UCHAR bmRFU:4;
822     UCHAR bmCommandStatus:2;
823 } UX_DEVICE_CLASS_CCID_SLOT_STATUS_REGISTER_BITMAP;
824 
825 /* Define CCID RDR_to_PC_DataBlock.  */
826 typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER_STRUCT
827 {
828     UCHAR       bMessageType;
829     UCHAR       dwLength[4];
830     UCHAR       bSlot;
831     UCHAR       bSeq;
832     UCHAR       bStatus;
833     UCHAR       bError;
834     UCHAR       bChainParameter;
835 } UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER;
836 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_CHAIN_PARAMETER(msg)         (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER*)(msg))->bChainParameter)
837 
838 /* Define CCID RDR_to_PC_SlotStatus.  */
839 typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER_STRUCT
840 {
841     UCHAR       bMessageType;
842     UCHAR       dwLength[4];
843     UCHAR       bSlot;
844     UCHAR       bSeq;
845     UCHAR       bStatus;
846     UCHAR       bError;
847     UCHAR       bClockStatus;
848 } UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER;
849 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_CLOCK_STATUS(msg)            (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)(msg))->bClockStatus)
850 
851 /* Define CCID RDR_to_PC_Parameters.  */
852 typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER_STRUCT
853 {
854     UCHAR       bMessageType;
855     UCHAR       dwLength[4];
856     UCHAR       bSlot;
857     UCHAR       bSeq;
858     UCHAR       bStatus;
859     UCHAR       bError;
860     UCHAR       bProtocolNum;
861 } UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER;
862 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PROTOCOL_NUM(msg)            (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER*)(msg))->bProtocolNum)
863 
864 typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0_STRUCT
865 {
866     UCHAR       bMessageType;
867     UCHAR       dwLength[4];
868     UCHAR       bSlot;
869     UCHAR       bSeq;
870     UCHAR       bStatus;
871     UCHAR       bError;
872     UCHAR       bProtocolNum;
873     UCHAR       bmFindexDindex;
874     UCHAR       bmTCCKST0;
875     UCHAR       bGuardTimeT0;
876     UCHAR       bWaitingIntegerT0;
877     UCHAR       bClockStop;
878 } UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0;
879 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0_LENGTH         5
880 
881 typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1_STRUCT
882 {
883     UCHAR       bMessageType;
884     UCHAR       dwLength[4];
885     UCHAR       bSlot;
886     UCHAR       bSeq;
887     UCHAR       bStatus;
888     UCHAR       bError;
889     UCHAR       bProtocolNum;
890     UCHAR       bmFindexDindex;
891     UCHAR       bmTCCKST1;
892     UCHAR       bGuardTimeT1;
893     UCHAR       bmWaitingIntegersT1;
894     UCHAR       bClockStop;
895     UCHAR       bIFSC;
896     UCHAR       bNadValue;
897 } UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1;
898 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1_LENGTH         7
899 
900 /* Define CCID RDR_to_PC_Escape.  */
901 typedef UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER UX_DEVICE_CLASS_CCID_RDR_TO_PC_ESCAPE_HEADER;
902 
903 /* Define CCID RDR_to_PC_DataRateAndClockFrequency.  */
904 typedef UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY_HEADER;
905 typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY_STRUCT
906 {
907     UCHAR       bMessageType;
908     UCHAR       dwLength[4];
909     UCHAR       bSlot;
910     UCHAR       bSeq;
911     UCHAR       bStatus;
912     UCHAR       bError;
913     UCHAR       bRFU;
914     UCHAR       dwClockFrequency[4];
915     UCHAR       dwDataRate[4];
916 } UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY;
917 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_CLOCK_FREQUENCY_SET(msg,v)   _ux_utility_long_put(((UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY*)(msg))->dwClockFrequency,(v))
918 #define UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_SET(msg,v)         _ux_utility_long_put(((UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY*)(msg))->dwDataRate,(v))
919 
920 
921 /* Define CCID message command handles, if command handle is not defined device
922    reports command not supported to host.
923    In RTOS mode return normal status code (_SUCCESS/_ERROR/...).
924    In standalone mode return task state status code (_STATE_NEXT/_STATE_ERROR/...).  */
925 typedef UINT (*UX_DEVICE_CLASS_CCID_HANDLE)(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*);
926 typedef struct UX_DEVICE_CLASS_CCID_HANDLES_STRUCT
927 {
928     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_icc_power_on;
929     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_icc_power_off;
930     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_get_slot_status;
931     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_xfr_block;
932     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_get_parameters;
933     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_reset_parameters;
934     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_set_parameters;
935     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_escape;
936     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_icc_clock;
937     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_t0_apdu;
938     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_secure;
939     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_mechanical;
940     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_abort;
941     UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_set_data_rate_and_clock_frequency;
942 } UX_DEVICE_CLASS_CCID_HANDLES;
943 
944 typedef struct UX_DEVICE_CLASS_CCID_COMMAND_SETT_STRUCT
945 {
946     UCHAR ux_device_class_ccid_command_sett_command_type;
947     UCHAR ux_device_class_ccid_command_sett_response_type;
948     UCHAR ux_device_class_ccid_command_sett_flags;
949     CHAR  ux_device_class_ccid_command_sett_handle_index;
950 } UX_DEVICE_CLASS_CCID_COMMAND_SETT;
951 
952 
953 /* Define CCID slot structure.  */
954 typedef struct UX_DEVICE_CLASS_CCID_SLOT_STRUCT
955 {
956     CHAR                    ux_device_class_ccid_slot_runner;
957     UCHAR                   ux_device_class_ccid_slot_flags;
958 
959     UCHAR                   ux_device_class_ccid_slot_icc_status;
960     UCHAR                   ux_device_class_ccid_slot_clock_status;
961 
962     UCHAR                   ux_device_class_ccid_slot_hw_error;
963     UCHAR                   ux_device_class_ccid_slot_hw_error_seq;
964 
965     UCHAR                   ux_device_class_ccid_slot_aborting_seq;
966     UCHAR                   ux_device_class_ccid_slot_aborting;
967 } UX_DEVICE_CLASS_CCID_SLOT;
968 
969 /* Define CCID runner structure.  */
970 typedef struct UX_DEVICE_CLASS_CCID_RUNNER_STRUCT
971 {
972     struct UX_DEVICE_CLASS_CCID_STRUCT
973                             *ux_device_class_ccid_runner_ccid;
974     UCHAR                   *ux_device_class_ccid_runner_command;
975     UCHAR                   *ux_device_class_ccid_runner_response;
976 
977     CHAR                    ux_device_class_ccid_runner_slot;
978     CHAR                    ux_device_class_ccid_runner_id;
979     CHAR                    ux_device_class_ccid_runner_command_index;
980 #if !defined(UX_DEVICE_STANDALONE)
981     UCHAR                   reserved;
982 
983     UX_THREAD               ux_device_class_ccid_runner_thread;
984     UCHAR                   *ux_device_class_ccid_runner_thread_stack;
985 #else
986     UCHAR                   ux_device_class_ccid_runner_state;
987 
988     UX_DEVICE_CLASS_CCID_HANDLE
989                             ux_device_class_ccid_runner_handle;
990     UX_DEVICE_CLASS_CCID_MESSAGES
991                             ux_device_class_ccid_runner_messages;
992 #endif
993 } UX_DEVICE_CLASS_CCID_RUNNER;
994 
995 /* Define Device CCID Class Calling Parameter structure */
996 typedef struct UX_DEVICE_CLASS_CCID_PARAMETER_STRUCT
997 {
998     VOID                    (*ux_device_class_ccid_instance_activate)(VOID *);
999     VOID                    (*ux_device_class_ccid_instance_deactivate)(VOID *);
1000     UX_DEVICE_CLASS_CCID_HANDLES
1001                             *ux_device_class_ccid_handles;
1002     ULONG                   *ux_device_class_ccid_clocks;
1003     ULONG                   *ux_device_class_ccid_data_rates;
1004     ULONG                   ux_device_class_ccid_max_transfer_length;
1005     UCHAR                   ux_device_class_ccid_max_n_slots;
1006     UCHAR                   ux_device_class_ccid_max_n_busy_slots;
1007     UCHAR                   ux_device_class_ccid_n_clocks;
1008     UCHAR                   ux_device_class_ccid_n_data_rates;
1009 } UX_DEVICE_CLASS_CCID_PARAMETER;
1010 
1011 
1012 /* Define CCID Class structure.  */
1013 
1014 typedef struct UX_DEVICE_CLASS_CCID_STRUCT
1015 {
1016     UX_SLAVE_INTERFACE      *ux_device_class_ccid_interface;
1017     UX_SLAVE_ENDPOINT       *ux_device_class_ccid_endpoint_out;
1018     UX_SLAVE_ENDPOINT       *ux_device_class_ccid_endpoint_in;
1019     UX_SLAVE_ENDPOINT       *ux_device_class_ccid_endpoint_notify;
1020 
1021 #if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
1022     UCHAR                   *ux_device_class_ccid_endpoint_buffer;
1023 #endif
1024 
1025     UX_DEVICE_CLASS_CCID_PARAMETER
1026                             ux_device_class_ccid_parameter;
1027 
1028     UX_DEVICE_CLASS_CCID_RUNNER
1029                             *ux_device_class_ccid_runners;
1030     UX_DEVICE_CLASS_CCID_SLOT
1031                             *ux_device_class_ccid_slots;
1032 
1033     UCHAR                   ux_device_class_ccid_header[UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH];
1034     SHORT                   ux_device_class_ccid_n_busy;
1035 
1036 #if !defined(UX_DEVICE_STANDALONE)
1037     UX_THREAD               ux_device_class_ccid_thread;
1038     UCHAR                   *ux_device_class_ccid_thread_stack;
1039 
1040     UX_THREAD               ux_device_class_ccid_notify_thread;
1041     UCHAR                   *ux_device_class_ccid_notify_thread_stack;
1042 
1043     UX_EVENT_FLAGS_GROUP    ux_device_class_ccid_events;
1044     UX_MUTEX                ux_device_class_ccid_mutex;
1045     UX_MUTEX                ux_device_class_ccid_response_mutex;
1046     UX_SEMAPHORE            ux_device_class_ccid_notify_semaphore;
1047 #else
1048     ULONG                   ux_device_class_ccid_flags;
1049 
1050     UCHAR                   ux_device_class_ccid_cmd_state;
1051     CHAR                    ux_device_class_ccid_cmd_index;
1052     UCHAR                   ux_device_class_ccid_rsp_state;
1053     UCHAR                   ux_device_class_ccid_notify_state;
1054 #endif
1055 } UX_DEVICE_CLASS_CCID;
1056 
1057 /* Device CCID endpoint buffer settings (when CCID owns buffer).  */
1058 #define UX_DEVICE_CLASS_CCID_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW                 \
1059     (UX_OVERFLOW_CHECK_MULC_ULONG(UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE, 2) ||  \
1060      UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE * 2,     \
1061                                  UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE))
1062 #define UX_DEVICE_CLASS_CCID_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE * 2 + UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE)
1063 #define UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid)       ((ccid) -> ux_device_class_ccid_endpoint_buffer)
1064 #define UX_DEVICE_CLASS_CCID_BULKIN_BUFFER(ccid)        (UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid) + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE)
1065 #define UX_DEVICE_CLASS_CCID_INTERRUPTIN_BUFFER(ccid)   (UX_DEVICE_CLASS_CCID_BULKIN_BUFFER(ccid) + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE)
1066 
1067 /* Device CCID flags.  */
1068 #define UX_DEVICE_CLASS_CCID_FLAG_LOCK          0x0001u
1069 #define UX_DEVICE_CLASS_CCID_FLAG_CMD_RSP       0x0010u
1070 
1071 #if defined(UX_DEVICE_STANDALONE)
1072 #define _ux_device_class_ccid_lock(ccid)    do {                                \
1073         UX_INTERRUPT_SAVE_AREA                                                  \
1074         UX_DISABLE                                                              \
1075         if (ccid->ux_device_class_ccid_flags & UX_DEVICE_CLASS_CCID_FLAG_LOCK)  \
1076         {                                                                       \
1077             UX_RESTORE                                                          \
1078             return(UX_BUSY);                                                    \
1079         }                                                                       \
1080         ccid->ux_device_class_ccid_flags |= UX_DEVICE_CLASS_CCID_FLAG_LOCK;     \
1081         UX_RESTORE                                                              \
1082     } while(0)
1083 #define _ux_device_class_ccid_unlock(ccid)  do {                                \
1084         ccid->ux_device_class_ccid_flags &= ~UX_DEVICE_CLASS_CCID_FLAG_LOCK;    \
1085     } while(0)
1086 #else
1087 #define _ux_device_class_ccid_lock(ccid)    _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex)
1088 #define _ux_device_class_ccid_unlock(ccid)  _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex)
1089 #endif
1090 
1091 /* Device CCID states.  */
1092 #define UX_DEVICE_CLASS_CCID_CMD_IDLE                               (UX_STATE_STEP + 0)
1093 #define UX_DEVICE_CLASS_CCID_CMD_START                              (UX_STATE_STEP + 1)
1094 #define UX_DEVICE_CLASS_CCID_CMD_WAIT                               (UX_STATE_STEP + 2)
1095 #define UX_DEVICE_CLASS_CCID_CMD_LOCK                               (UX_STATE_STEP + 3)
1096 #define UX_DEVICE_CLASS_CCID_CMD_PROCESS                            (UX_STATE_STEP + 4)
1097 #define UX_DEVICE_CLASS_CCID_CMD_RSP_START                          (UX_STATE_STEP + 5)
ccidCmdStateName(const UINT s)1098 static inline const char *ccidCmdStateName(const UINT s)
1099 {
1100     switch(s)
1101     {
1102     case UX_DEVICE_CLASS_CCID_CMD_IDLE:     return("cmdIDLE");
1103     case UX_DEVICE_CLASS_CCID_CMD_START:    return("cmdSTART");
1104     case UX_DEVICE_CLASS_CCID_CMD_WAIT:     return("cmdWAIT");
1105     case UX_DEVICE_CLASS_CCID_CMD_LOCK:     return("cmdLOCK");
1106     case UX_DEVICE_CLASS_CCID_CMD_PROCESS:  return("cmdPROCESS");
1107     case UX_DEVICE_CLASS_CCID_CMD_RSP_START:return("cmdRSP_START");
1108     default: return("cmd?");
1109     }
1110 }
1111 
1112 #define UX_DEVICE_CLASS_CCID_RUNNER_IDLE                            (UX_STATE_STEP + 0)
1113 #define UX_DEVICE_CLASS_CCID_RUNNER_START                           (UX_STATE_STEP + 1)
1114 #define UX_DEVICE_CLASS_CCID_RUNNER_HANDLE                          (UX_STATE_STEP + 2)
1115 #define UX_DEVICE_CLASS_CCID_RUNNER_RSP_START                       (UX_STATE_STEP + 3)
ccidRunnerStateName(const UINT s)1116 static inline const char *ccidRunnerStateName(const UINT s)
1117 {
1118     switch(s)
1119     {
1120     case UX_DEVICE_CLASS_CCID_RUNNER_IDLE:          return("runnerIDLE");
1121     case UX_DEVICE_CLASS_CCID_RUNNER_START:         return("runnerSTART");
1122     case UX_DEVICE_CLASS_CCID_RUNNER_HANDLE:        return("runnerHANDLE");
1123     case UX_DEVICE_CLASS_CCID_RUNNER_RSP_START:     return("runnerRSP_START");
1124     default: return("runner?");
1125     }
1126 }
1127 
1128 #define UX_DEVICE_CLASS_CCID_RSP_IDLE                               (UX_STATE_STEP + 0)
1129 #define UX_DEVICE_CLASS_CCID_RSP_START                              (UX_STATE_STEP + 1)
1130 #define UX_DEVICE_CLASS_CCID_RSP_WAIT                               (UX_STATE_STEP + 2)
1131 #define UX_DEVICE_CLASS_CCID_RSP_LOCK                               (UX_STATE_STEP + 3)
1132 #define UX_DEVICE_CLASS_CCID_RSP_UPDATE                             (UX_STATE_STEP + 4)
1133 #define UX_DEVICE_CLASS_CCID_RSP_DONE                               (UX_STATE_STEP + 5)
ccidRspStateName(const UINT s)1134 static inline const char *ccidRspStateName(const UINT s)
1135 {
1136     switch(s)
1137     {
1138     case UX_DEVICE_CLASS_CCID_RSP_IDLE:     return("rspIDLE");
1139     case UX_DEVICE_CLASS_CCID_RSP_START:    return("rspSTART");
1140     case UX_DEVICE_CLASS_CCID_RSP_WAIT:     return("rspWAIT");
1141     case UX_DEVICE_CLASS_CCID_RSP_LOCK:     return("rspLOCK");
1142     case UX_DEVICE_CLASS_CCID_RSP_UPDATE:   return("rspUPDATE");
1143     case UX_DEVICE_CLASS_CCID_RSP_DONE:     return("rspDONE");
1144     default: return("rsp?");
1145     }
1146 }
1147 
1148 #define UX_DEVICE_CLASS_CCID_NOTIFY_IDLE                            (UX_STATE_STEP + 0)
1149 #define UX_DEVICE_CLASS_CCID_NOTIFY_LOCK                            (UX_STATE_STEP + 1)
1150 #define UX_DEVICE_CLASS_CCID_NOTIFY_START                           (UX_STATE_STEP + 2)
1151 #define UX_DEVICE_CLASS_CCID_NOTIFY_WAIT                            (UX_STATE_STEP + 3)
ccidNotifyStateName(const UINT s)1152 static inline const char *ccidNotifyStateName(const UINT s)
1153 {
1154     switch(s)
1155     {
1156     case UX_DEVICE_CLASS_CCID_NOTIFY_IDLE:     return("notifyIDLE");
1157     case UX_DEVICE_CLASS_CCID_NOTIFY_LOCK:     return("notifyLOCK");
1158     case UX_DEVICE_CLASS_CCID_NOTIFY_START:    return("notifySTART");
1159     case UX_DEVICE_CLASS_CCID_NOTIFY_WAIT:     return("notifyWAIT");
1160     default: return("notify?");
1161     }
1162 }
1163 
1164 /* Define Device CCID command settings.  */
1165 extern const UX_DEVICE_CLASS_CCID_COMMAND_SETT _ux_device_class_ccid_command_sett[];
1166 
1167 /* Define Device CCID Class prototypes.  */
1168 UINT  _ux_device_class_ccid_initialize(UX_SLAVE_CLASS_COMMAND *command);
1169 UINT  _ux_device_class_ccid_uninitialize(UX_SLAVE_CLASS_COMMAND *command);
1170 UINT  _ux_device_class_ccid_activate(UX_SLAVE_CLASS_COMMAND *command);
1171 UINT  _ux_device_class_ccid_deactivate(UX_SLAVE_CLASS_COMMAND *command);
1172 UINT  _ux_device_class_ccid_control_request(UX_SLAVE_CLASS_COMMAND *command);
1173 
1174 VOID  _ux_device_class_ccid_thread_entry(ULONG ccid_instance);
1175 VOID  _ux_device_class_ccid_notify_thread_entry(ULONG ccid_instance);
1176 VOID  _ux_device_class_ccid_runner_thread_entry(ULONG runner_instance);
1177 
1178 UINT  _ux_device_class_ccid_tasks_run(VOID *instance);
1179 UINT  _ux_device_class_ccid_notify_task_run(UX_DEVICE_CLASS_CCID *ccid);
1180 UINT  _ux_device_class_ccid_runner_task_run(UX_DEVICE_CLASS_CCID *ccid);
1181 
1182 UINT  _ux_device_class_ccid_control_abort(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq);
1183 
1184 UINT  _ux_device_class_ccid_response(UX_DEVICE_CLASS_CCID *ccid, UCHAR *buffer, ULONG length);
1185 
1186 UINT  _ux_device_class_ccid_entry(UX_SLAVE_CLASS_COMMAND *command);
1187 
1188 UINT  _ux_device_class_ccid_icc_insert(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq_start);
1189 UINT  _ux_device_class_ccid_icc_remove(UX_DEVICE_CLASS_CCID *ccid, ULONG slot);
1190 UINT  _ux_device_class_ccid_auto_seq_start(UX_DEVICE_CLASS_CCID *ccid, ULONG slot);
1191 UINT  _ux_device_class_ccid_auto_seq_done(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG icc_status);
1192 UINT  _ux_device_class_ccid_time_extension(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG wt);
1193 UINT  _ux_device_class_ccid_hardware_error(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG error);
1194 
1195 UINT  _uxe_device_class_ccid_icc_insert(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq_start);
1196 UINT  _uxe_device_class_ccid_icc_remove(UX_DEVICE_CLASS_CCID *ccid, ULONG slot);
1197 UINT  _uxe_device_class_ccid_auto_seq_done(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG icc_status);
1198 UINT  _uxe_device_class_ccid_time_extension(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG wt);
1199 UINT  _uxe_device_class_ccid_hardware_error(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG error);
1200 
1201 /* Define Device CCID Class API prototypes.  */
1202 
1203 #define ux_device_class_ccid_entry               _ux_device_class_ccid_entry
1204 
1205 #if defined(UX_DEVICE_CLASS_CCID_ENABLE_ERROR_CHECKING)
1206 
1207 #define ux_device_class_ccid_icc_insert          _uxe_device_class_ccid_icc_insert
1208 #define ux_device_class_ccid_icc_remove          _uxe_device_class_ccid_icc_remove
1209 #define ux_device_class_ccid_auto_seq_done       _uxe_device_class_ccid_auto_seq_done
1210 #define ux_device_class_ccid_time_extension      _uxe_device_class_ccid_time_extension
1211 #define ux_device_class_ccid_hardware_error      _uxe_device_class_ccid_hardware_error
1212 
1213 #else
1214 
1215 #define ux_device_class_ccid_icc_insert          _ux_device_class_ccid_icc_insert
1216 #define ux_device_class_ccid_icc_remove          _ux_device_class_ccid_icc_remove
1217 #define ux_device_class_ccid_auto_seq_done       _ux_device_class_ccid_auto_seq_done
1218 #define ux_device_class_ccid_time_extension      _ux_device_class_ccid_time_extension
1219 #define ux_device_class_ccid_hardware_error      _ux_device_class_ccid_hardware_error
1220 
1221 #endif
1222 
1223 /* Determine if a C++ compiler is being used.  If so, complete the standard
1224    C conditional started above.  */
1225 #ifdef __cplusplus
1226 }
1227 #endif
1228 
1229 #endif /* UX_DEVICE_CLASS_CCID_H */
1230