summaryrefslogtreecommitdiff
path: root/common/usbx_device_classes/inc/ux_device_class_ccid.h
blob: a5b54a8a3c28cd5a2c41a455b3c2e12900b0b0c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
/***************************************************************************
 * Copyright (c) 2024 Microsoft Corporation
 * Copyright (c) 2026-present Eclipse ThreadX contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * SPDX-License-Identifier: MIT
 **************************************************************************/

/**************************************************************************/
/**************************************************************************/
/**                                                                       */
/** USBX Component                                                        */
/**                                                                       */
/**   Device CCID Class                                                   */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/

/**************************************************************************/
/*                                                                        */
/*  COMPONENT DEFINITION                                   RELEASE        */
/*                                                                        */
/*    ux_device_class_ccid.h                              PORTABLE C      */
/*                                                           6.3.0        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Chaoqiong Xiao, Microsoft Corporation                               */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This file defines the equivalences for the USBX Device Class CCID   */
/*    (Smart-Card Integrated Circuit(s) Card) component.                  */
/*                                                                        */
/**************************************************************************/

#ifndef UX_DEVICE_CLASS_CCID_H
#define UX_DEVICE_CLASS_CCID_H

/* Determine if a C++ compiler is being used.  If so, ensure that standard
   C is used to process the API information.  */

#ifdef   __cplusplus

/* Yes, C++ compiler is present.  Use standard C.  */
extern   "C" {
#endif

/* Internal option: enable the basic USBX error checking. This define is typically used
   while debugging application.  */
#if defined(UX_ENABLE_ERROR_CHECKING) && !defined(UX_DEVICE_CLASS_CCID_ENABLE_ERROR_CHECKING)
#define UX_DEVICE_CLASS_CCID_ENABLE_ERROR_CHECKING
#endif


/* Notification/interrupt endpoint buffer size, must be larger than max packet size in framework, and aligned in 4-bytes.  */
#define UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE                          16

/* Bulk endpoints buffer size, must be larger than dwMaxCCIDMessageLength and wMaxPacketSize in framework, and aligned in 4-bytes.  */
#define UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE                               UX_SLAVE_REQUEST_DATA_MAX_LENGTH


#if !defined(UX_DEVICE_STANDALONE)

/* Define CCID max number of slots, 32 for 32 bit data width.  */
#define UX_DEVICE_CLASS_CCID_MAX_N_SLOTS                                    (4*8)
#else

/* To optimize the max number of slots fixed to 1.  */
#define UX_DEVICE_CLASS_CCID_MAX_N_SLOTS                                    1
#endif

/* Thread stack size, for RTOS mode only.  */
#define UX_DEVICE_CLASS_CCID_THREAD_STACK_SIZE                              UX_THREAD_STACK_SIZE
#define UX_DEVICE_CLASS_CCID_NOTIFY_THREAD_STACK_SIZE                       UX_THREAD_STACK_SIZE
#define UX_DEVICE_CLASS_CCID_RUNNER_THREAD_STACK_SIZE                       UX_THREAD_STACK_SIZE

/* Define CCID Class USB Class constants.  */
#define UX_DEVICE_CLASS_CCID_CLASS                                          0x0B

#define UX_DEVICE_CLASS_CCID_SUBCLASS                                       0

#define UX_DEVICE_CLASS_CCID_PROTOCOL                                       0

#define UX_DEVICE_CLASS_CCID_BCD_CCID_1_10                                  0x0110

#define UX_DEVICE_CLASS_CCID_VOLTAGE_SUPPORT_5_0                            1u
#define UX_DEVICE_CLASS_CCID_VOLTAGE_SUPPORT_3_0                            2u
#define UX_DEVICE_CLASS_CCID_VOLTAGE_SUPPORT_1_8                            4u

#define UX_DEVICE_CLASS_CCID_PROTOCOLS_T0                                   1u
#define UX_DEVICE_CLASS_CCID_PROTOCOLS_T1                                   2u

#define UX_DEVICE_CLASS_CCID_SYNCH_PROTOCOLS_2_WIRE                         1u
#define UX_DEVICE_CLASS_CCID_SYNCH_PROTOCOLS_3_WIRE                         2u
#define UX_DEVICE_CLASS_CCID_SYNCH_PROTOCOLS_I2C                            4u

#define UX_DEVICE_CLASS_CCID_MECHANICAL_NO_SPECIAL                          0u
#define UX_DEVICE_CLASS_CCID_MECHANICAL_ACCEPT                              1u
#define UX_DEVICE_CLASS_CCID_MECHANICAL_EJECT                               2u
#define UX_DEVICE_CLASS_CCID_MECHANICAL_CAPTURE                             4u
#define UX_DEVICE_CLASS_CCID_MECHANICAL_LOCK_UNLOCK                         8u

#define UX_DEVICE_CLASS_CCID_FEATURES_NO_SPECIAL                            0u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_PARAMETER_ATR                    2u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_ACTIVATION                       4u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_VOLTAGE                          8u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_CLOCK_FREQUENCY                  0x10u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_BAUD_RATE                        0x20u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_PARAMETER_NEGOTIATION            0x40u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_PPS                              0x80u
#define UX_DEVICE_CLASS_CCID_FEATURES_CAN_SET_ICC_IN_CLOCK_STOP             0x100u
#define UX_DEVICE_CLASS_CCID_FEATURES_NAD_NOT_0_ACCEPTED                    0x200u
#define UX_DEVICE_CLASS_CCID_FEATURES_AUTO_IFSD_EXCHANGE_1ST                0x400u
#define UX_DEVICE_CLASS_CCID_FEATURES_TPUD_EXCHANGES                        0x10000u
#define UX_DEVICE_CLASS_CCID_FEATURES_SHORT_APUD_EXCHANGES                  0x20000u
#define UX_DEVICE_CLASS_CCID_FEATURES_SHORT_AND_EXTENDED_APUD_EXCHANGES     0x40000u
#define UX_DEVICE_CLASS_CCID_FEATURES_WAKEUP_ON_INSERTION_REMOVAL           0x100000u

#define UX_DEVICE_CLASS_CCID_LCD_LAYOUT_NO_LCD                              0
#define UX_DEVICE_CLASS_CCID_LCD_LAYOUT(n_lines,n_per_line)                 (((n_lines) << 8) | (n_per_line))

#define UX_DEVICE_CLASS_CCID_PIN_SUPPORT_VERIFICATION                       1u
#define UX_DEVICE_CLASS_CCID_PIN_SUPPORT_MODIFICATION                       2u

#define UX_DEVICE_CLASS_CCID_MAX_CCID_MESSAGE_EXT_APDU_MIN                  (261+10)
#define UX_DEVICE_CLASS_CCID_MAX_CCID_MESSAGE_EXT_APDU_MAX                  (65544+10)


/* Device CCID Requests */
#define UX_DEVICE_CLASS_CCID_ABORT                                          0x01
#define UX_DEVICE_CLASS_CCID_GET_CLOCK_FREQUENCIES                          0x02
#define UX_DEVICE_CLASS_CCID_GET_DATA_RATES                                 0x03


/* CCID message offsets, values.  */

/* General.  */
#define UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH                          10

#define UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE                            0
#define UX_DEVICE_CLASS_CCID_OFFSET_LENGTH                                  1
#define UX_DEVICE_CLASS_CCID_OFFSET_SLOT                                    5
#define UX_DEVICE_CLASS_CCID_OFFSET_SEQ                                     6

#define UX_DEVICE_CLASS_CCID_OFFSET_DATA                                    10

/* PC_to_RDR_IccPowerOn.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_POWER_SELECT                            7
#define UX_DEVICE_CLASS_CCID_POWER_SELECT_AUTO                              0
#define UX_DEVICE_CLASS_CCID_POWER_SELECT_5_0_V                             1
#define UX_DEVICE_CLASS_CCID_POWER_SELECT_3_0_V                             2
#define UX_DEVICE_CLASS_CCID_POWER_SELECT_1_8_V                             3

/* PC_to_RDR_XfrBlock/PC_to_RDR_Secure.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_BWI                                     7
#define UX_DEVICE_CLASS_CCID_OFFSET_LEVEL_PARAMETER                         8
#define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_RFU                            0x00u
#define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_BEGIN_END                      0x00u
#define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_BEGIN_CONTINUE                 0x01u
#define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_CONTINUE_END                   0x02u
#define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_CONTINUE                       0x03u
#define UX_DEVICE_CLASS_CCID_LEVEL_PARAMETER_EMPTY_DATA                     0x10u

/* PC_to_RDR_SetParameters.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_SET_PARAMETERS_PROTOCOL_NUM             7

#define UX_DEVICE_CLASS_CCID_PROTOCOL_T_0                                   0
#define UX_DEVICE_CLASS_CCID_PROTOCOL_T_1                                   1
#define UX_DEVICE_CLASS_CCID_PROTOCOL_2_WIRE                                0x80
#define UX_DEVICE_CLASS_CCID_PROTOCOL_3_WIRE                                0x81
#define UX_DEVICE_CLASS_CCID_PROTOCOL_I2C                                   0x82

/* Parameters.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_FI_DI                                   10

#define UX_DEVICE_CLASS_CCID_OFFSET_TCCKS_T0                                11
#define UX_DEVICE_CLASS_CCID_OFFSET_GUARD_TIME_T0                           12
#define UX_DEVICE_CLASS_CCID_OFFSET_WAITING_INTEGER_T0                      13
#define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_STOP_T0                           14

#define UX_DEVICE_CLASS_CCID_OFFSET_TCCKS_T1                                11
#define UX_DEVICE_CLASS_CCID_OFFSET_GUARD_TIME_T1                           12
#define UX_DEVICE_CLASS_CCID_OFFSET_WAITING_INTEGERS_T1                     13
#define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_STOP_T1                           14
#define UX_DEVICE_CLASS_CCID_OFFSET_IFSC                                    15
#define UX_DEVICE_CLASS_CCID_OFFSET_NAD_VALUE                               16

/* PC_to_RDR_IccClock.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_COMMAND                           7
#define UX_DEVICE_CLASS_CCID_CLOCK_COMMAND_RESTART                          0
#define UX_DEVICE_CLASS_CCID_CLOCK_COMMAND_STOP                             1

/* PC_to_RDR_T0APDU.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_CHANGES                                 7
#define UX_DEVICE_CLASS_CCID_OFFSET_CLASS_GET_RESPONSE                      8
#define UX_DEVICE_CLASS_CCID_OFFSET_CLASS_ENVELOPE                          9
#define UX_DEVICE_CLASS_CCID_CHANGE_CLASS_GET_RESPONSE                      (1u << 0)
#define UX_DEVICE_CLASS_CCID_CHANGE_CLASS_ENVELOPE                          (1u << 1)

/* PC_to_RDR_Secure.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_OPERATION                           10
#define UX_DEVICE_CLASS_CCID_PIN_VERIFICATION                               0
#define UX_DEVICE_CLASS_CCID_PIN_MODIFICATION                               1
#define UX_DEVICE_CLASS_CCID_PIN_TRANSFER                                   2
#define UX_DEVICE_CLASS_CCID_PIN_WAIT_ICC_RESP                              3
#define UX_DEVICE_CLASS_CCID_PIN_CANCEL                                     4
#define UX_DEVICE_CLASS_CCID_PIN_RESEND_I_BLOCK                             5
#define UX_DEVICE_CLASS_CCID_PIN_NEXT_APDU                                  6

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_DATA                                11

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_TIME_OUT                            11
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_FORMAT_STRING                       12

#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_FORMAT_TYPE_MASK                 (0x3u << 0)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_BINARY                           (0x0u << 0)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_BCD                              (0x1u << 0)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_ASCII                            (0x2u << 0)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_JUSTIFICATION                    (0x1u << 2)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_LEFT_JUSTIFY                     (0x0u << 2)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_RIGHT_JUSTIFY                    (0x1u << 2)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_POSITION_MASK                    (0xFu << 3)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_POSITION(v)                      (((v) >> 3) & 0xFu)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_UNIT_TYPE                        (0x1u << 7)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_UNIT_BITS                        (0x0u << 7)
#define UX_DEVICE_CLASS_CCID_FORMAT_STRING_UNIT_BYTES                       (0x1u << 7)

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_PIN_BLOCK_STRING                    13
#define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_LENGTH_BITS_MASK          (0xFu << 3)
#define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_BLOCK_SIZE_BYTES_MASK     (0xFu << 0)
#define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_LENGTH_BITS(v)            ((v) >> 4) & 0xFu)
#define UX_DEVICE_CLASS_CCID_PIN_BLOCK_STRING_PIN_BLOCK_SIZE_BYTES(v)       ((v) >> 0) & 0xFu)

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_PIN_LENGTH_FORMAT                   14
#define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_UNIT_TYPE                    (1u << 4)
#define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_UNIT_BITS                    (0u << 4)
#define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_UNIT_BYTES                   (1u << 4)
#define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_POSITION_MASK                (0xFu << 0)
#define UX_DEVICE_CLASS_CCID_PIN_LENGTH_FORMAT_POSITION(v)                  (((v) << 0) & 0xFu)

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_TIME_OUT                     11
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_FORMAT_STRING                12
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_BLOCK_STRING             13
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_LENGTH_FORMAT            14

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_MAX_EXTRA_DIGIT          15
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_MAX_EXTRA_DIGIT_MIN      16
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_MAX_EXTRA_DIGIT_MAX      15

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_ENTRY_VALIDATION_CONDITION   17
#define UX_DEVICE_CLASS_CCID_PIN_ENTRY_VALIDATION_MAX_SIZE                  1u
#define UX_DEVICE_CLASS_CCID_PIN_ENTRY_VALIDATION_KEY_PRESS                 2u
#define UX_DEVICE_CLASS_CCID_PIN_ENTRY_VALIDATION_TIMEOUT                   4u

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_NUMBER_MESSAGE               18
#define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_NO                          0
#define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_1                           0
#define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_2                           0
#define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_3                           0
#define UX_DEVICE_CLASS_CCID_PIN_NUMBER_MESSAGE_DEFAULT                     0xFF

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_LANG_ID                      19
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_MSG_INDEX                    21
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_TEO_PROLOGUE                 22
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_VERIFI_PIN_APDU                     25

#define UX_DEVICE_CLASS_CCID_PIN_MESSAGE_INSERT_PROMPT                      0
#define UX_DEVICE_CLASS_CCID_PIN_MESSAGE_MODIFY_PROMPT                      1
#define UX_DEVICE_CLASS_CCID_PIN_MESSAGE_NEW_CONFIRM_PROMPT                 2

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TIME_OUT                     11
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_FORMAT_STRING                12
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_BLOCK_STRING             13
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_LENGTH_FORMAT            14

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_INSERTION_OFFSET_OLD         15
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_INSERTION_OFFSET_NEW         16

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_MAX_EXTRA_DIGIT          17
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_MAX_EXTRA_DIGIT_MIN      18
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_MAX_EXTRA_DIGIT_MAX      17

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_CONFIRM_PIN                  19
#define UX_DEVICE_CLASS_CCID_CONFIRM_PIN_CONFIRM_REQUESTED                  (1u << 0)
#define UX_DEVICE_CLASS_CCID_CONFIRM_PIN_ENTRY_REQUESTED                    (1u << 1)

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_ENTRY_VALIDATION_CONDITION   20
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_NUMBER_MESSAGE               21
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_LANG_ID                      22
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_MSG_INDEX1                   24
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_MSG_INDEX2                   25
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_MSG_INDEX3                   26
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TEO_PROLOGUE1                25
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TEO_PROLOGUE2                26
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_TEO_PROLOGUE3                27
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_APDU1                    28
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_APDU2                    29
#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_MODIFI_PIN_APDU3                    30

#define UX_DEVICE_CLASS_CCID_OFFSET_PIN_NEXT_APDU_TEO_PROLOGUE              11

/* PC_to_RDR_Mechanical.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_FUNCTION                                7
#define UX_DEVICE_CLASS_CCID_FUNCTION_ACCEPT_CARD                           0x01
#define UX_DEVICE_CLASS_CCID_FUNCTION_EJECT_CARD                            0x02
#define UX_DEVICE_CLASS_CCID_FUNCTION_CAPTURE_CARD                          0x03
#define UX_DEVICE_CLASS_CCID_FUNCTION_LOCK_CARD                             0x04
#define UX_DEVICE_CLASS_CCID_FUNCTION_UNLOCK_CARD                           0x05

/* PC_to_RDR_SetDataRateAndClockFrequency/RDR_to_PC_DataRateAndClockFrequency.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_FREQUENCY                         10
#define UX_DEVICE_CLASS_CCID_OFFSET_DATA_RATE                               14

/* RDR_to_PC_   */
#define UX_DEVICE_CLASS_CCID_OFFSET_STATUS                                  7
#define UX_DEVICE_CLASS_CCID_OFFSET_ERROR                                   8

/* RDR_to_PC_DataBlock.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_CHAIN_PARAMETER                         9
#define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_BEGIN_END                      0x00
#define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_BEGIN_CONTINUE                 0x01
#define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_CONTINUE_END                   0x02
#define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_CONTINUE                       0x03
#define UX_DEVICE_CLASS_CCID_CHAIN_PARAMETER_EMPTY                          0x10

/* RDR_to_PC_SlotStatus.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_CLOCK_STATUS                            9

/* RDR_to_PC_Parameters.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_PARAMETERS_PROTOCOL_NUM                 9

#define UX_DEVICE_CLASS_CCID_PARAMETERS_T0_LENGTH                           5
#define UX_DEVICE_CLASS_CCID_PARAMETERS_T1_LENGTH                           7

/* RDR_to_PC_NotifySlotChange.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_SLOT_ICC_STATE                          1

/* RDR_to_PC_HardwareError.  */
#define UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SLOT                           1
#define UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SEQ                            2
#define UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_CODE                           3
#define UX_DEVICE_CLASS_CCID_HW_ERROR_OVERCURRENT                           1


/* CCID bMessageTypes.  */
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON                         0x62
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_OFF                        0x63
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_SLOT_STATUS                      0x64
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK                            0x6F
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_PARAMETERS                       0x6C
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_RESET_PARAMETERS                     0x6D
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS                       0x61
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ESCAPE                               0x6B
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK                            0x6E
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU                              0x6A
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE                               0x69
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL                           0x71
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT                                0x72
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQ         0x73

#define UX_DEVICE_CLASS_CCID_N_COMMANDS                                     14

#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK                           0x80
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS                          0x81
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS                           0x82
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_ESCAPE                               0x83
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQ             0x84

#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_NOTIFY_SLOT_CHANGE                   0x50
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_HARDWARE_ERROR                       0x51

#define UX_DEVICE_CLASS_CCID_COMMAND_ABORTABLE(bMessageType)                \
    (((bMessageType) == 0x62) || ((bMessageType) == 0x6F) ||                \
     ((bMessageType) == 0x6B) || ((bMessageType) == 0x69) ||                \
     ((bMessageType) == 0x71) || ((bMessageType) == 0x72))

#define UX_DEVICE_CLASS_CCID_COMMAND_HW_ERROR_CHECK(bMessageType)           \
    (((bMessageType) != 0x63) && ((bMessageType) != 0x6B) &&                \
     ((bMessageType) != 0x6A) && ((bMessageType) != 0x72) &&                \
     ((bMessageType) != 0x73))

#define UX_DEVICE_CLASS_CCID_COMMAND_AUTO_SEQUENCE_CHECK(bMessageType)      \
    (((bMessageType) != 0x62) && ((bMessageType) != 0x65) &&                \
     ((bMessageType) != 0x6B) && ((bMessageType) != 0x6A) &&                \
     ((bMessageType) != 0x72) && ((bMessageType) != 0x73))

#define UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_BLOCK(m)                     \
    ((m) == 0x62 || (m) == 0x6F || (m) == 0x69)
#define UX_DEVICE_CLASS_CCID_COMMAND_RESP_SLOT_STATUS(m)                    \
    ((m) == 0x63 || (m) == 0x64 || (m) == 0x6E || (m) == 0x6A ||            \
     (m) == 0x71 || (m) == 0x72 || (m) == 0x65)
#define UX_DEVICE_CLASS_CCID_COMMAND_RESP_PARAMETERS(m)                     \
    ((m) == 0x6C || (m) == 0x6D || (m) == 0x61)
#define UX_DEVICE_CLASS_CCID_COMMAND_RESP_ESCAPE(m)                         \
    ((m) == 0x6B)
#define UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_RATE_AND_CLOCK_FREQ(m)       \
    ((m) == 0x73)

#define UX_DEVICE_CLASS_CCID_COMMAND_RESP_TYPE(m)                           \
    (UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_BLOCK(m) ? 0x80 :               \
     UX_DEVICE_CLASS_CCID_COMMAND_RESP_SLOT_STATUS(m) ? 0x81 :              \
     UX_DEVICE_CLASS_CCID_COMMAND_RESP_PARAMETERS(m) ? 0x82 :               \
     UX_DEVICE_CLASS_CCID_COMMAND_RESP_ESCAPE(m) ? 0x83 :                   \
     UX_DEVICE_CLASS_CCID_COMMAND_RESP_DATA_RATE_AND_CLOCK_FREQ(m) ? 0x84 : \
     0)

/* CCID Slot error binary code.  */
#define UX_DEVICE_CLASS_CCID_CMD_ABORTED                                    0xFF
#define UX_DEVICE_CLASS_CCID_ICC_MUTE                                       0xFE
#define UX_DEVICE_CLASS_CCID_XFR_PARITY_ERROR                               0xFD
#define UX_DEVICE_CLASS_CCID_XFR_OVERRUN                                    0xFC
#define UX_DEVICE_CLASS_CCID_HW_ERROR                                       0xFB
#define UX_DEVICE_CLASS_CCID_BAD_ATR_TS                                     0xF8
#define UX_DEVICE_CLASS_CCID_BAD_ATR_TCK                                    0xF7
#define UX_DEVICE_CLASS_CCID_ICC_PROTOCOL_NOT_SUPPORTED                     0xF6
#define UX_DEVICE_CLASS_CCID_ICC_CLASS_NOT_SUPPORTED                        0xF5
#define UX_DEVICE_CLASS_CCID_PROCEDURE_BYTE_CONFLICT                        0xF4
#define UX_DEVICE_CLASS_CCID_DEACTIVATED_PROTOCOL                           0xF3
#define UX_DEVICE_CLASS_CCID_BUSY_WITH_AUTO_SEQUENCE                        0xF2
#define UX_DEVICE_CLASS_CCID_PIN_TIMEOUT                                    0xF0
#define UX_DEVICE_CLASS_CCID_PIN_CANCELLED                                  0xEF
#define UX_DEVICE_CLASS_CCID_CMD_SLOT_BUSY                                  0xE0


/* CCID bStatus.  */
#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_TIME_EXTENSION                     0x80

#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_ACTIVE                         (0x0u)
#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_INACTIVE                       (0x1u)
#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_NOT_PRESENT                    (0x2u)
#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_MASK                           (0x3u)

#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_NO_ERROR                       (0x0u << 6)
#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_FAILED                         (0x1u << 6)
#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_TIME_EXTENSION                 (0x2u << 6)
#define UX_DEVICE_CLASS_CCID_SLOT_STATUS_CMD_MASK                           (0x3u << 6)

#define UX_DEVICE_CLASS_CCID_SLOT_STATUS(bmICCStatus, bmCommandStatus)      ((bmICCStatus) | ((bmCommandStatus) << 6))
#define UX_DEVICE_CLASS_CCID_ICC_ACTIVE                                     0
#define UX_DEVICE_CLASS_CCID_ICC_INACTIVE                                   1
#define UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT                                2
#define UX_DEVICE_CLASS_CCID_CMD_NO_ERROR                                   0
#define UX_DEVICE_CLASS_CCID_CMD_FAILED                                     1
#define UX_DEVICE_CLASS_CCID_CMD_TIME_EXTENSION                             2


/* CCID events.  */
#define UX_DEVICE_CLASS_CCID_EVENT_SLOT(n)                                  (1u<<(n))


/* CCID flags.  */
#define UX_DEVICE_CLASS_CCID_FLAG_ABORTABLE                                 0x80u
#define UX_DEVICE_CLASS_CCID_FLAG_BUSY                                      0x40u

#define UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE                             0x01u
#define UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_HW_ERROR                           0x02u

#define UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING                           0x04u
#define UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR                                  0x08u


#define UX_DEVICE_CLASS_CCID_COMMAND_FLAG_ABORTABLE(bMessageType)           \
    (UX_DEVICE_CLASS_CCID_COMMAND_ABORTABLE(bMessageType) ?                 \
     UX_DEVICE_CLASS_CCID_FLAG_ABORTABLE : 0)

#define UX_DEVICE_CLASS_CCID_COMMAND_FLAG_AUTO_SEQUENCE_CHECK(bMessageType) \
    (UX_DEVICE_CLASS_CCID_COMMAND_AUTO_SEQUENCE_CHECK(bMessageType) ?       \
     UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING : 0)

#define UX_DEVICE_CLASS_CCID_COMMAND_FLAG_HW_ERROR_CHECK(bMessageType)      \
    (UX_DEVICE_CLASS_CCID_COMMAND_HW_ERROR_CHECK(bMessageType) ?            \
     UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR : 0)

#define UX_DEVICE_CLASS_CCID_COMMAND_FLAGS(bMessageType)                    \
    (UX_DEVICE_CLASS_CCID_COMMAND_FLAG_ABORTABLE(bMessageType) |            \
     UX_DEVICE_CLASS_CCID_COMMAND_FLAG_AUTO_SEQUENCE_CHECK(bMessageType) |  \
     UX_DEVICE_CLASS_CCID_COMMAND_FLAG_HW_ERROR_CHECK(bMessageType))


/* CCID message structures.  */

/* General message for both PC_to_RDR and RDR_to_PC.  */
typedef struct UX_DEVICE_CLASS_CCID_MESSAGES_STRUCT
{
    UCHAR       *ux_device_class_ccid_messages_pc_to_rdr;
    UCHAR       *ux_device_class_ccid_messages_rdr_to_pc;
    ULONG       ux_device_class_ccid_messages_rdr_to_pc_length; /* Total buffer length including header.  */
} UX_DEVICE_CLASS_CCID_MESSAGES;

/* Define CCID message header.  */
typedef struct UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bRFU[3];
} UX_DEVICE_CLASS_CCID_MESSAGE_HEADER;
#define UX_DEVICE_CLASS_CCID_MESSAGE_TYPE(msg)                      (((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->bMessageType)
#define UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_GET(msg)                _ux_utility_long_get(((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->dwLength)
#define UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(msg,len)            _ux_utility_long_put(((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->dwLength, (len))
#define UX_DEVICE_CLASS_CCID_MESSAGE_SLOT(msg)                      (((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->bSlot)
#define UX_DEVICE_CLASS_CCID_MESSAGE_SEQ(msg)                       (((UX_DEVICE_CLASS_CCID_MESSAGE_HEADER*)(msg))->bSeq)
#define UX_DEVICE_CLASS_CCID_MESSAGE_DATA(msg)                      (((UCHAR *)(msg) + UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH))

/* Define CCID PC_to_RDR_IccPowerOn.  */
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bPowerSelect;
    UCHAR       bRFU[2];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_POWER_SELECT(msg)            (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_ON_HEADER*)(msg))->bPowerSelect)

/* Define CCID PC_to_RDR_IccPowerOff.  */
typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_POWER_OFF_HEADER;

/* Define CCID PC_to_RDR_GetSlotStatus.  */
typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_SLOT_STATUS_HEADER;

/* Define CCID PC_to_RDR_XfrBlock.  */
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bBWI;
    USHORT      wLevelParameter;
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_BWI(msg)                     (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER*)(msg))->bBWI)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_LEVEL_PARAMETER(msg)         (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER*)(msg))->wLevelParameter)

/* Define CCID PC_to_RDR_GetParameters.  */
typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_GET_PARAMETERS_HEADER;

/* Define CCID PC_to_RDR_ResetParameters.  */
typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_RESET_PARAMETERS_HEADER;

/* Define CCID PC_to_RDR_SetParameters.  */
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bProtocolNum;
    UCHAR       bRFU[2];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PROTOCOL_NUM(msg)            (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_HEADER*)(msg))->bProtocolNum)
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bProtocolNum;
    UCHAR       bRFU[2];
    UCHAR       bmFindexDindex;
    UCHAR       bmTCCKST0;
    UCHAR       bGuardTimeT0;
    UCHAR       bWaitingIntegerT0;
    UCHAR       bClockStop;
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T0_LENGTH     5
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bProtocolNum;
    UCHAR       bRFU[2];
    UCHAR       bmFindexDindex;
    UCHAR       bmTCCKST1;
    UCHAR       bGuardTimeT1;
    UCHAR       bmWaitingIntegersT1;
    UCHAR       bClockStop;
    UCHAR       bIFSC;
    UCHAR       bNadValue;
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_PARAMETERS_T1_LENGTH     7

/* Define CCID PC_to_RDR_Escape.  */
typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_ESCAPE_HEADER;

/* Define CCID PC_to_RDR_IccClock.  */
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bClockCommand;
    UCHAR       bRFU[2];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_CLOCK_COMMAND(msg)           (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_ICC_CLOCK_HEADER*)(msg))->bClockCommand)

/* Define CCID PC_to_RDR_T0APDU.  */
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bmChanges;
    UCHAR       bClassGetResponse;
    UCHAR       bClassEnvelope;
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_CHANGES(msg)         (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_T0_APDU_HEADER*)(msg))->bmChanges)
#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)
#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)

/* Define CCID PC_to_RDR_Secure.  */
typedef UX_DEVICE_CLASS_CCID_PC_TO_RDR_XFR_BLOCK_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_SECURE_HEADER;

typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bBWI;
    USHORT      wLevelParameter;
    UCHAR       bPINOperation;
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_BWI(msg)                 (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER*)(msg))->bBWI)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_LEVEL_PARAMETER(msg)     (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER*)(msg))->wLevelParameter)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_OPERATION(msg)           (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_HEADER*)(msg))->bPINOperation)

typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bBWI;
    USHORT      wLevelParameter;
    UCHAR       bPINOperation;

    UCHAR       bTimeOut;
    UCHAR       bmFormatString;
    UCHAR       bmPINBlockString;
    UCHAR       bmPINLengthFormat;

    UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
    UCHAR       bEntryValidationCondition;
    UCHAR       bNumberMessage;
    UCHAR       wLangId[2];
    UCHAR       bMsgIndex;
    UCHAR       bTeoPrologue[3];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_TIMEOUT(msg)             (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bTimeOut)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_FORMAT_STRING(msg)       (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bmFormatString)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_BLOCK_STRING(msg)        (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bmPINBlockString)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_LENGTH_FORMAT(msg)       (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION*)(msg))->bmPINLengthFormat)

#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)
#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])
#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])
#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)
#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)
#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)
#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)
#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)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_DATA(msg)                           ((UCHAR*)(msg) + 25)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_VERIFICATION_APDU(msg)                           ((UCHAR*)(msg) + 25)

typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bBWI;
    USHORT      wLevelParameter;
    UCHAR       bPINOperation;

    UCHAR       bTimeOut;
    UCHAR       bmFormatString;
    UCHAR       bmPINBlockString;
    UCHAR       bmPINLengthFormat;

    UCHAR       bInsertionOffsetOld;
    UCHAR       bInsertionOffsetNew;
    UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
    UCHAR       bConfirmPIN;
    UCHAR       bEntryValidationCondition;
    UCHAR       bNumberMessage;
    UCHAR       wLangId[2];
    UCHAR       bMsgIndex1;
    UCHAR       bTeoPrologue[3];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION;
typedef UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1_TEO_PROLOGUE(msg)   ((UCHAR*)(msg) + 25)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1_DATA(msg)           ((UCHAR*)(msg) + 28)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION1_APDU(msg)           ((UCHAR*)(msg) + 28)
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bBWI;
    USHORT      wLevelParameter;
    UCHAR       bPINOperation;
    UCHAR       bTimeOut;
    UCHAR       bmFormatString;
    UCHAR       bmPINBlockString;
    UCHAR       bmPINLengthFormat;
    UCHAR       bInsertionOffsetOld;
    UCHAR       bInsertionOffsetNew;
    UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
    UCHAR       bConfirmPIN;
    UCHAR       bEntryValidationCondition;
    UCHAR       bNumberMessage;
    UCHAR       wLangId[2];
    UCHAR       bMsgIndex1;
    UCHAR       bMsgIndex2;
    UCHAR       bTeoPrologue[3];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_TEO_PROLOGUE(msg)   ((UCHAR*)(msg) + 26)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_DATA(msg)           ((UCHAR*)(msg) + 29)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION2_APDU(msg)           ((UCHAR*)(msg) + 29)
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bBWI;
    USHORT      wLevelParameter;
    UCHAR       bPINOperation;
    UCHAR       bTimeOut;
    UCHAR       bmFormatString;
    UCHAR       bmPINBlockString;
    UCHAR       bmPINLengthFormat;
    UCHAR       bInsertionOffsetOld;
    UCHAR       bInsertionOffsetNew;
    UCHAR       wPINMaxExtraDigit[2]; /* XXYY, XX: min size, YY: max size.  */
    UCHAR       bConfirmPIN;
    UCHAR       bEntryValidationCondition;
    UCHAR       bNumberMessage;
    UCHAR       wLangId[2];
    UCHAR       bMsgIndex1;
    UCHAR       bMsgIndex2;
    UCHAR       bMsgIndex3;
    UCHAR       bTeoPrologue[3];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_TEO_PROLOGUE(msg)   ((UCHAR*)(msg) + 27)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_DATA(msg)           ((UCHAR*)(msg) + 30)
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_PIN_MODIFICATION3_APDU(msg)           ((UCHAR*)(msg) + 30)


/* Define CCID PC_to_RDR_Mechanical.  */
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bFunction;
    UCHAR       bRFU[2];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER;
#define UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_FUNCTION(msg)     (((UX_DEVICE_CLASS_CCID_PC_TO_RDR_MECHANICAL_HEADER*)(msg))->bFunction)

/* Define CCID PC_to_RDR_Abort.  */
typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_ABORT_HEADER;

/* Define CCID PC_to_RDR_SetDataRateAndClockFrequency.  */
typedef UX_DEVICE_CLASS_CCID_MESSAGE_HEADER UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY_HEADER;
typedef struct UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bRFU[3];
    UCHAR       dwClockFrequency[4];
    UCHAR       dwDataRate[4];
} UX_DEVICE_CLASS_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY;
#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)
#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)

/* Define CCID RDR_to_PC_ header.  */
typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bStatus;
    UCHAR       bError;
    UCHAR       bRFU;
} UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER;
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_STATUS(msg)                  (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER*)(msg))->bStatus)
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_ERROR(msg)                   (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER*)(msg))->bError)

/* Define CCID Slot Status Register.  */
typedef struct UX_DEVICE_CLASS_CCID_SLOT_STATUS_REGISTER_BITMAP_STRUCT
{
    UCHAR bmICCStatus:2;
    UCHAR bmRFU:4;
    UCHAR bmCommandStatus:2;
} UX_DEVICE_CLASS_CCID_SLOT_STATUS_REGISTER_BITMAP;

/* Define CCID RDR_to_PC_DataBlock.  */
typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bStatus;
    UCHAR       bError;
    UCHAR       bChainParameter;
} UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER;
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_CHAIN_PARAMETER(msg)         (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_BLOCK_HEADER*)(msg))->bChainParameter)

/* Define CCID RDR_to_PC_SlotStatus.  */
typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bStatus;
    UCHAR       bError;
    UCHAR       bClockStatus;
} UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER;
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_CLOCK_STATUS(msg)            (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER*)(msg))->bClockStatus)

/* Define CCID RDR_to_PC_Parameters.  */
typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bStatus;
    UCHAR       bError;
    UCHAR       bProtocolNum;
} UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER;
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PROTOCOL_NUM(msg)            (((UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_HEADER*)(msg))->bProtocolNum)

typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bStatus;
    UCHAR       bError;
    UCHAR       bProtocolNum;
    UCHAR       bmFindexDindex;
    UCHAR       bmTCCKST0;
    UCHAR       bGuardTimeT0;
    UCHAR       bWaitingIntegerT0;
    UCHAR       bClockStop;
} UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0;
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T0_LENGTH         5

typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bStatus;
    UCHAR       bError;
    UCHAR       bProtocolNum;
    UCHAR       bmFindexDindex;
    UCHAR       bmTCCKST1;
    UCHAR       bGuardTimeT1;
    UCHAR       bmWaitingIntegersT1;
    UCHAR       bClockStop;
    UCHAR       bIFSC;
    UCHAR       bNadValue;
} UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1;
#define UX_DEVICE_CLASS_CCID_RDR_TO_PC_PARAMETERS_T1_LENGTH         7

/* Define CCID RDR_to_PC_Escape.  */
typedef UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER UX_DEVICE_CLASS_CCID_RDR_TO_PC_ESCAPE_HEADER;

/* Define CCID RDR_to_PC_DataRateAndClockFrequency.  */
typedef UX_DEVICE_CLASS_CCID_RDR_TO_PC_HEADER UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY_HEADER;
typedef struct UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY_STRUCT
{
    UCHAR       bMessageType;
    UCHAR       dwLength[4];
    UCHAR       bSlot;
    UCHAR       bSeq;
    UCHAR       bStatus;
    UCHAR       bError;
    UCHAR       bRFU;
    UCHAR       dwClockFrequency[4];
    UCHAR       dwDataRate[4];
} UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY;
#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))
#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))


/* Define CCID message command handles, if command handle is not defined device
   reports command not supported to host.
   In RTOS mode return normal status code (_SUCCESS/_ERROR/...).
   In standalone mode return task state status code (_STATE_NEXT/_STATE_ERROR/...).  */
typedef UINT (*UX_DEVICE_CLASS_CCID_HANDLE)(ULONG slot, UX_DEVICE_CLASS_CCID_MESSAGES*);
typedef struct UX_DEVICE_CLASS_CCID_HANDLES_STRUCT
{
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_icc_power_on;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_icc_power_off;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_get_slot_status;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_xfr_block;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_get_parameters;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_reset_parameters;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_set_parameters;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_escape;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_icc_clock;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_t0_apdu;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_secure;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_mechanical;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_abort;
    UX_DEVICE_CLASS_CCID_HANDLE ux_device_class_ccid_handles_set_data_rate_and_clock_frequency;
} UX_DEVICE_CLASS_CCID_HANDLES;

typedef struct UX_DEVICE_CLASS_CCID_COMMAND_SETT_STRUCT
{
    UCHAR ux_device_class_ccid_command_sett_command_type;
    UCHAR ux_device_class_ccid_command_sett_response_type;
    UCHAR ux_device_class_ccid_command_sett_flags;
    CHAR  ux_device_class_ccid_command_sett_handle_index;
} UX_DEVICE_CLASS_CCID_COMMAND_SETT;


/* Define CCID slot structure.  */
typedef struct UX_DEVICE_CLASS_CCID_SLOT_STRUCT
{
    CHAR                    ux_device_class_ccid_slot_runner;
    UCHAR                   ux_device_class_ccid_slot_flags;

    UCHAR                   ux_device_class_ccid_slot_icc_status;
    UCHAR                   ux_device_class_ccid_slot_clock_status;

    UCHAR                   ux_device_class_ccid_slot_hw_error;
    UCHAR                   ux_device_class_ccid_slot_hw_error_seq;

    UCHAR                   ux_device_class_ccid_slot_aborting_seq;
    UCHAR                   ux_device_class_ccid_slot_aborting;
} UX_DEVICE_CLASS_CCID_SLOT;

/* Define CCID runner structure.  */
typedef struct UX_DEVICE_CLASS_CCID_RUNNER_STRUCT
{
    struct UX_DEVICE_CLASS_CCID_STRUCT
                            *ux_device_class_ccid_runner_ccid;
    UCHAR                   *ux_device_class_ccid_runner_command;
    UCHAR                   *ux_device_class_ccid_runner_response;

    CHAR                    ux_device_class_ccid_runner_slot;
    CHAR                    ux_device_class_ccid_runner_id;
    CHAR                    ux_device_class_ccid_runner_command_index;
#if !defined(UX_DEVICE_STANDALONE)
    UCHAR                   reserved;

    UX_THREAD               ux_device_class_ccid_runner_thread;
    UCHAR                   *ux_device_class_ccid_runner_thread_stack;
#else
    UCHAR                   ux_device_class_ccid_runner_state;

    UX_DEVICE_CLASS_CCID_HANDLE
                            ux_device_class_ccid_runner_handle;
    UX_DEVICE_CLASS_CCID_MESSAGES
                            ux_device_class_ccid_runner_messages;
#endif
} UX_DEVICE_CLASS_CCID_RUNNER;

/* Define Device CCID Class Calling Parameter structure */
typedef struct UX_DEVICE_CLASS_CCID_PARAMETER_STRUCT
{
    VOID                    (*ux_device_class_ccid_instance_activate)(VOID *);
    VOID                    (*ux_device_class_ccid_instance_deactivate)(VOID *);
    UX_DEVICE_CLASS_CCID_HANDLES
                            *ux_device_class_ccid_handles;
    ULONG                   *ux_device_class_ccid_clocks;
    ULONG                   *ux_device_class_ccid_data_rates;
    ULONG                   ux_device_class_ccid_max_transfer_length;
    UCHAR                   ux_device_class_ccid_max_n_slots;
    UCHAR                   ux_device_class_ccid_max_n_busy_slots;
    UCHAR                   ux_device_class_ccid_n_clocks;
    UCHAR                   ux_device_class_ccid_n_data_rates;
} UX_DEVICE_CLASS_CCID_PARAMETER;


/* Define CCID Class structure.  */

typedef struct UX_DEVICE_CLASS_CCID_STRUCT
{
    UX_SLAVE_INTERFACE      *ux_device_class_ccid_interface;
    UX_SLAVE_ENDPOINT       *ux_device_class_ccid_endpoint_out;
    UX_SLAVE_ENDPOINT       *ux_device_class_ccid_endpoint_in;
    UX_SLAVE_ENDPOINT       *ux_device_class_ccid_endpoint_notify;

#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
    UCHAR                   *ux_device_class_ccid_endpoint_buffer;
#endif

    UX_DEVICE_CLASS_CCID_PARAMETER
                            ux_device_class_ccid_parameter;

    UX_DEVICE_CLASS_CCID_RUNNER
                            *ux_device_class_ccid_runners;
    UX_DEVICE_CLASS_CCID_SLOT
                            *ux_device_class_ccid_slots;

    UCHAR                   ux_device_class_ccid_header[UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH];
    SHORT                   ux_device_class_ccid_n_busy;

#if !defined(UX_DEVICE_STANDALONE)
    UX_THREAD               ux_device_class_ccid_thread;
    UCHAR                   *ux_device_class_ccid_thread_stack;

    UX_THREAD               ux_device_class_ccid_notify_thread;
    UCHAR                   *ux_device_class_ccid_notify_thread_stack;

    UX_EVENT_FLAGS_GROUP    ux_device_class_ccid_events;
    UX_MUTEX                ux_device_class_ccid_mutex;
    UX_MUTEX                ux_device_class_ccid_response_mutex;
    UX_SEMAPHORE            ux_device_class_ccid_notify_semaphore;
#else
    ULONG                   ux_device_class_ccid_flags;

    UCHAR                   ux_device_class_ccid_cmd_state;
    CHAR                    ux_device_class_ccid_cmd_index;
    UCHAR                   ux_device_class_ccid_rsp_state;
    UCHAR                   ux_device_class_ccid_notify_state;
#endif
} UX_DEVICE_CLASS_CCID;

/* Device CCID endpoint buffer settings (when CCID owns buffer).  */
#define UX_DEVICE_CLASS_CCID_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW                 \
    (UX_OVERFLOW_CHECK_MULC_ULONG(UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE, 2) ||  \
     UX_OVERFLOW_CHECK_ADD_ULONG(UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE * 2,     \
                                 UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE))
#define UX_DEVICE_CLASS_CCID_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE * 2 + UX_DEVICE_CLASS_CCID_INTERRUPT_BUFFER_SIZE)
#define UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid)       ((ccid) -> ux_device_class_ccid_endpoint_buffer)
#define UX_DEVICE_CLASS_CCID_BULKIN_BUFFER(ccid)        (UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid) + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE)
#define UX_DEVICE_CLASS_CCID_INTERRUPTIN_BUFFER(ccid)   (UX_DEVICE_CLASS_CCID_BULKIN_BUFFER(ccid) + UX_DEVICE_CLASS_CCID_BULK_BUFFER_SIZE)

/* Device CCID flags.  */
#define UX_DEVICE_CLASS_CCID_FLAG_LOCK          0x0001u
#define UX_DEVICE_CLASS_CCID_FLAG_CMD_RSP       0x0010u

#if defined(UX_DEVICE_STANDALONE)
#define _ux_device_class_ccid_lock(ccid)    do {                                \
        UX_INTERRUPT_SAVE_AREA                                                  \
        UX_DISABLE                                                              \
        if (ccid->ux_device_class_ccid_flags & UX_DEVICE_CLASS_CCID_FLAG_LOCK)  \
        {                                                                       \
            UX_RESTORE                                                          \
            return(UX_BUSY);                                                    \
        }                                                                       \
        ccid->ux_device_class_ccid_flags |= UX_DEVICE_CLASS_CCID_FLAG_LOCK;     \
        UX_RESTORE                                                              \
    } while(0)
#define _ux_device_class_ccid_unlock(ccid)  do {                                \
        ccid->ux_device_class_ccid_flags &= ~UX_DEVICE_CLASS_CCID_FLAG_LOCK;    \
    } while(0)
#else
#define _ux_device_class_ccid_lock(ccid)    _ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex)
#define _ux_device_class_ccid_unlock(ccid)  _ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex)
#endif

/* Device CCID states.  */
#define UX_DEVICE_CLASS_CCID_CMD_IDLE                               (UX_STATE_STEP + 0)
#define UX_DEVICE_CLASS_CCID_CMD_START                              (UX_STATE_STEP + 1)
#define UX_DEVICE_CLASS_CCID_CMD_WAIT                               (UX_STATE_STEP + 2)
#define UX_DEVICE_CLASS_CCID_CMD_LOCK                               (UX_STATE_STEP + 3)
#define UX_DEVICE_CLASS_CCID_CMD_PROCESS                            (UX_STATE_STEP + 4)
#define UX_DEVICE_CLASS_CCID_CMD_RSP_START                          (UX_STATE_STEP + 5)
static inline const char *ccidCmdStateName(const UINT s)
{
    switch(s)
    {
    case UX_DEVICE_CLASS_CCID_CMD_IDLE:     return("cmdIDLE");
    case UX_DEVICE_CLASS_CCID_CMD_START:    return("cmdSTART");
    case UX_DEVICE_CLASS_CCID_CMD_WAIT:     return("cmdWAIT");
    case UX_DEVICE_CLASS_CCID_CMD_LOCK:     return("cmdLOCK");
    case UX_DEVICE_CLASS_CCID_CMD_PROCESS:  return("cmdPROCESS");
    case UX_DEVICE_CLASS_CCID_CMD_RSP_START:return("cmdRSP_START");
    default: return("cmd?");
    }
}

#define UX_DEVICE_CLASS_CCID_RUNNER_IDLE                            (UX_STATE_STEP + 0)
#define UX_DEVICE_CLASS_CCID_RUNNER_START                           (UX_STATE_STEP + 1)
#define UX_DEVICE_CLASS_CCID_RUNNER_HANDLE                          (UX_STATE_STEP + 2)
#define UX_DEVICE_CLASS_CCID_RUNNER_RSP_START                       (UX_STATE_STEP + 3)
static inline const char *ccidRunnerStateName(const UINT s)
{
    switch(s)
    {
    case UX_DEVICE_CLASS_CCID_RUNNER_IDLE:          return("runnerIDLE");
    case UX_DEVICE_CLASS_CCID_RUNNER_START:         return("runnerSTART");
    case UX_DEVICE_CLASS_CCID_RUNNER_HANDLE:        return("runnerHANDLE");
    case UX_DEVICE_CLASS_CCID_RUNNER_RSP_START:     return("runnerRSP_START");
    default: return("runner?");
    }
}

#define UX_DEVICE_CLASS_CCID_RSP_IDLE                               (UX_STATE_STEP + 0)
#define UX_DEVICE_CLASS_CCID_RSP_START                              (UX_STATE_STEP + 1)
#define UX_DEVICE_CLASS_CCID_RSP_WAIT                               (UX_STATE_STEP + 2)
#define UX_DEVICE_CLASS_CCID_RSP_LOCK                               (UX_STATE_STEP + 3)
#define UX_DEVICE_CLASS_CCID_RSP_UPDATE                             (UX_STATE_STEP + 4)
#define UX_DEVICE_CLASS_CCID_RSP_DONE                               (UX_STATE_STEP + 5)
static inline const char *ccidRspStateName(const UINT s)
{
    switch(s)
    {
    case UX_DEVICE_CLASS_CCID_RSP_IDLE:     return("rspIDLE");
    case UX_DEVICE_CLASS_CCID_RSP_START:    return("rspSTART");
    case UX_DEVICE_CLASS_CCID_RSP_WAIT:     return("rspWAIT");
    case UX_DEVICE_CLASS_CCID_RSP_LOCK:     return("rspLOCK");
    case UX_DEVICE_CLASS_CCID_RSP_UPDATE:   return("rspUPDATE");
    case UX_DEVICE_CLASS_CCID_RSP_DONE:     return("rspDONE");
    default: return("rsp?");
    }
}

#define UX_DEVICE_CLASS_CCID_NOTIFY_IDLE                            (UX_STATE_STEP + 0)
#define UX_DEVICE_CLASS_CCID_NOTIFY_LOCK                            (UX_STATE_STEP + 1)
#define UX_DEVICE_CLASS_CCID_NOTIFY_START                           (UX_STATE_STEP + 2)
#define UX_DEVICE_CLASS_CCID_NOTIFY_WAIT                            (UX_STATE_STEP + 3)
static inline const char *ccidNotifyStateName(const UINT s)
{
    switch(s)
    {
    case UX_DEVICE_CLASS_CCID_NOTIFY_IDLE:     return("notifyIDLE");
    case UX_DEVICE_CLASS_CCID_NOTIFY_LOCK:     return("notifyLOCK");
    case UX_DEVICE_CLASS_CCID_NOTIFY_START:    return("notifySTART");
    case UX_DEVICE_CLASS_CCID_NOTIFY_WAIT:     return("notifyWAIT");
    default: return("notify?");
    }
}

/* Define Device CCID command settings.  */
extern const UX_DEVICE_CLASS_CCID_COMMAND_SETT _ux_device_class_ccid_command_sett[];

/* Define Device CCID Class prototypes.  */
UINT  _ux_device_class_ccid_initialize(UX_SLAVE_CLASS_COMMAND *command);
UINT  _ux_device_class_ccid_uninitialize(UX_SLAVE_CLASS_COMMAND *command);
UINT  _ux_device_class_ccid_activate(UX_SLAVE_CLASS_COMMAND *command);
UINT  _ux_device_class_ccid_deactivate(UX_SLAVE_CLASS_COMMAND *command);
UINT  _ux_device_class_ccid_control_request(UX_SLAVE_CLASS_COMMAND *command);

VOID  _ux_device_class_ccid_thread_entry(ULONG ccid_instance);
VOID  _ux_device_class_ccid_notify_thread_entry(ULONG ccid_instance);
VOID  _ux_device_class_ccid_runner_thread_entry(ULONG runner_instance);

UINT  _ux_device_class_ccid_tasks_run(VOID *instance);
UINT  _ux_device_class_ccid_notify_task_run(UX_DEVICE_CLASS_CCID *ccid);
UINT  _ux_device_class_ccid_runner_task_run(UX_DEVICE_CLASS_CCID *ccid);

UINT  _ux_device_class_ccid_control_abort(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq);

UINT  _ux_device_class_ccid_response(UX_DEVICE_CLASS_CCID *ccid, UCHAR *buffer, ULONG length);

UINT  _ux_device_class_ccid_entry(UX_SLAVE_CLASS_COMMAND *command);

UINT  _ux_device_class_ccid_icc_insert(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq_start);
UINT  _ux_device_class_ccid_icc_remove(UX_DEVICE_CLASS_CCID *ccid, ULONG slot);
UINT  _ux_device_class_ccid_auto_seq_start(UX_DEVICE_CLASS_CCID *ccid, ULONG slot);
UINT  _ux_device_class_ccid_auto_seq_done(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG icc_status);
UINT  _ux_device_class_ccid_time_extension(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG wt);
UINT  _ux_device_class_ccid_hardware_error(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG error);

UINT  _uxe_device_class_ccid_icc_insert(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq_start);
UINT  _uxe_device_class_ccid_icc_remove(UX_DEVICE_CLASS_CCID *ccid, ULONG slot);
UINT  _uxe_device_class_ccid_auto_seq_done(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG icc_status);
UINT  _uxe_device_class_ccid_time_extension(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG wt);
UINT  _uxe_device_class_ccid_hardware_error(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG error);

/* Define Device CCID Class API prototypes.  */

#define ux_device_class_ccid_entry               _ux_device_class_ccid_entry

#if defined(UX_DEVICE_CLASS_CCID_ENABLE_ERROR_CHECKING)

#define ux_device_class_ccid_icc_insert          _uxe_device_class_ccid_icc_insert
#define ux_device_class_ccid_icc_remove          _uxe_device_class_ccid_icc_remove
#define ux_device_class_ccid_auto_seq_done       _uxe_device_class_ccid_auto_seq_done
#define ux_device_class_ccid_time_extension      _uxe_device_class_ccid_time_extension
#define ux_device_class_ccid_hardware_error      _uxe_device_class_ccid_hardware_error

#else

#define ux_device_class_ccid_icc_insert          _ux_device_class_ccid_icc_insert
#define ux_device_class_ccid_icc_remove          _ux_device_class_ccid_icc_remove
#define ux_device_class_ccid_auto_seq_done       _ux_device_class_ccid_auto_seq_done
#define ux_device_class_ccid_time_extension      _ux_device_class_ccid_time_extension
#define ux_device_class_ccid_hardware_error      _ux_device_class_ccid_hardware_error

#endif

/* Determine if a C++ compiler is being used.  If so, complete the standard
   C conditional started above.  */
#ifdef __cplusplus
}
#endif

#endif /* UX_DEVICE_CLASS_CCID_H */