00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <USBD_Config.h>
00049
00050 #include "USBLib_Trace.h"
00051 #include "USBD.h"
00052 #include "USBDDriver.h"
00053 #include "USBRequests.h"
00054
00055 #include "cciddriver.h"
00056 #include "cciddriverdescriptors.h"
00057 #include "iso7816_4.h"
00058 #include <string.h>
00059
00060
00061
00062
00063
00064
00065
00066 #define CCIDDriverDescriptors_PRODUCTID 0x6129
00067
00068
00069 #define CCIDDriverDescriptors_VENDORID 0x03EB
00070
00071
00072 #define CCIDDriverDescriptors_RELEASE 0x0100
00073
00074
00075
00076 #define MIN(a, b) ((a < b) ? a : b)
00077
00078
00079
00080
00081
00082 #pragma pack(1)
00083 #if defined (__CC_ARM )
00084 #elif defined (__ICCARM__)
00085 #define __attribute__(...)
00086 #elif defined (__GNUC__)
00087 #endif
00088
00089
00090
00091
00092
00093
00094
00095 typedef struct _CCIDDriverConfigurationDescriptors {
00096
00097
00098 USBConfigurationDescriptor configuration;
00099
00100 USBInterfaceDescriptor interface;
00101
00102 CCIDDescriptor ccid;
00103
00104 USBEndpointDescriptor bulkOut;
00105
00106 USBEndpointDescriptor bulkIn;
00107
00108 USBEndpointDescriptor interruptIn;
00109
00110 } __attribute__ ((packed)) CCIDDriverConfigurationDescriptors;
00111
00112 #pragma pack()
00113
00114
00115
00116
00117
00118
00119
00120 typedef struct {
00121
00122
00123 USBDDriver usbdDriver;
00124
00125 S_ccid_bulk_in_header sCcidMessage;
00126
00127 S_ccid_bulk_out_header sCcidCommand;
00128
00129 unsigned char BufferINT[4];
00130
00131 unsigned char ProtocolDataStructure[10];
00132
00133 unsigned char bProtocol;
00134
00135
00136
00137
00138
00139
00140
00141 unsigned char SlotStatus;
00142
00143 } CCIDDriver;
00144
00145
00146
00147
00148
00149
00150 static CCIDDriver ccidDriver;
00151
00152
00153 static const USBDeviceDescriptor deviceDescriptor = {
00154
00155 sizeof(USBDeviceDescriptor),
00156 USBGenericDescriptor_DEVICE,
00157 USBDeviceDescriptor_USB2_00,
00158 0,
00159 0,
00160 0,
00161 CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
00162 CCIDDriverDescriptors_VENDORID,
00163 CCIDDriverDescriptors_PRODUCTID,
00164 CCIDDriverDescriptors_RELEASE,
00165 1,
00166 2,
00167 3,
00168 1
00169
00170 };
00171
00172
00173
00174 static const CCIDDriverConfigurationDescriptors configurationDescriptorsFS = {
00175
00176
00177 {
00178 sizeof(USBConfigurationDescriptor),
00179 USBGenericDescriptor_CONFIGURATION,
00180 sizeof(CCIDDriverConfigurationDescriptors),
00181 1,
00182 1,
00183 0,
00184 USBD_BMATTRIBUTES,
00185 USBConfigurationDescriptor_POWER(100)
00186 },
00187
00188
00189
00190 {
00191 sizeof(USBInterfaceDescriptor),
00192 USBGenericDescriptor_INTERFACE,
00193 0,
00194 0,
00195 3,
00196 SMART_CARD_DEVICE_CLASS,
00197 0,
00198 0,
00199 0
00200
00201 },
00202 {
00203 sizeof(CCIDDescriptor),
00204 CCID_DECRIPTOR_TYPE,
00205 CCID1_10,
00206 0,
00207 VOLTS_5_0,
00208 PROTOCOL_TO,
00209 3580,
00210 3580,
00211 0,
00212 9600,
00213 9600,
00214 0,
00215 0xfe,
00216 0,
00217 0,
00218
00219 CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU,
00220 0x0000010F,
00221 0xFF,
00222 0xFF,
00223 0,
00224 0,
00225 1
00226 },
00227
00228
00229 {
00230 sizeof(USBEndpointDescriptor),
00231 USBGenericDescriptor_ENDPOINT,
00232 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT),
00233 USBEndpointDescriptor_BULK,
00234 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT),
00235 USBEndpointDescriptor_MAXBULKSIZE_FS),
00236 0x00
00237
00238 },
00239
00240
00241 {
00242 sizeof(USBEndpointDescriptor),
00243 USBGenericDescriptor_ENDPOINT,
00244 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_DATA_IN),
00245 USBEndpointDescriptor_BULK,
00246 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN),
00247 USBEndpointDescriptor_MAXBULKSIZE_FS),
00248 0x00
00249
00250 },
00251
00252
00253 {
00254 sizeof(USBEndpointDescriptor),
00255 USBGenericDescriptor_ENDPOINT,
00256 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION),
00257 USBEndpointDescriptor_INTERRUPT,
00258 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION),
00259 USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
00260 0x10
00261 }
00262 };
00263
00264 #if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
00265 static const CCIDDriverConfigurationDescriptors configurationDescriptorsHS = {
00266
00267
00268 {
00269 sizeof(USBConfigurationDescriptor),
00270 USBGenericDescriptor_CONFIGURATION,
00271 sizeof(CCIDDriverConfigurationDescriptors),
00272 1,
00273 1,
00274 0,
00275 USBD_BMATTRIBUTES,
00276 USBConfigurationDescriptor_POWER(100)
00277 },
00278
00279
00280
00281 {
00282 sizeof(USBInterfaceDescriptor),
00283 USBGenericDescriptor_INTERFACE,
00284 0,
00285 0,
00286 3,
00287 SMART_CARD_DEVICE_CLASS,
00288 0,
00289 0,
00290 0
00291
00292 },
00293 {
00294 sizeof(CCIDDescriptor),
00295 CCID_DECRIPTOR_TYPE,
00296 CCID1_10,
00297 0,
00298 VOLTS_5_0,
00299 PROTOCOL_TO,
00300 3580,
00301 3580,
00302 0,
00303 9600,
00304 9600,
00305 0,
00306 0xfe,
00307 0,
00308 0,
00309
00310 CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU,
00311 0x0000010F,
00312 0xFF,
00313 0xFF,
00314 0,
00315 0,
00316 1
00317 },
00318
00319 {
00320 sizeof(USBEndpointDescriptor),
00321 USBGenericDescriptor_ENDPOINT,
00322 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT),
00323 USBEndpointDescriptor_BULK,
00324 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT),
00325 USBEndpointDescriptor_MAXBULKSIZE_HS),
00326 0x00
00327
00328 },
00329
00330
00331 {
00332 sizeof(USBEndpointDescriptor),
00333 USBGenericDescriptor_ENDPOINT,
00334 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_DATA_IN),
00335 USBEndpointDescriptor_BULK,
00336 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN),
00337 USBEndpointDescriptor_MAXBULKSIZE_HS),
00338 0x00
00339
00340 },
00341
00342
00343 {
00344 sizeof(USBEndpointDescriptor),
00345 USBGenericDescriptor_ENDPOINT,
00346 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION),
00347 USBEndpointDescriptor_INTERRUPT,
00348 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION),
00349 USBEndpointDescriptor_MAXINTERRUPTSIZE_HS),
00350 0x10
00351 }
00352 };
00353
00354
00355
00356 const USBDeviceQualifierDescriptor deviceQualifierDescriptor = {
00357
00358 sizeof(USBDeviceQualifierDescriptor),
00359 USBGenericDescriptor_DEVICEQUALIFIER,
00360 USBDeviceDescriptor_USB2_00,
00361 0x00,
00362 0x00,
00363 0x00,
00364 CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
00365 0x01,
00366 0x00
00367
00368 };
00369
00370
00371
00372 static const CCIDDriverConfigurationDescriptors sOtherSpeedConfigurationFS = {
00373
00374
00375
00376 {
00377 sizeof(USBConfigurationDescriptor),
00378 USBGenericDescriptor_OTHERSPEEDCONFIGURATION,
00379 sizeof(CCIDDriverConfigurationDescriptors),
00380 1,
00381 1,
00382 0,
00383 USBD_BMATTRIBUTES,
00384 USBConfigurationDescriptor_POWER(100)
00385 },
00386
00387
00388
00389 {
00390 sizeof(USBInterfaceDescriptor),
00391 USBGenericDescriptor_INTERFACE,
00392 0,
00393 0,
00394 3,
00395 SMART_CARD_DEVICE_CLASS,
00396 0,
00397 0,
00398 0
00399 },
00400 {
00401 sizeof(CCIDDescriptor),
00402 CCID_DECRIPTOR_TYPE,
00403 CCID1_10,
00404 0,
00405 VOLTS_5_0,
00406 PROTOCOL_TO,
00407 3580,
00408 3580,
00409 0,
00410 9600,
00411 9600,
00412 0,
00413 0xfe,
00414 0,
00415 0,
00416
00417 CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU,
00418 0x0000010F,
00419 0xFF,
00420 0xFF,
00421 0,
00422 0,
00423 1
00424 },
00425
00426
00427 {
00428 sizeof(USBEndpointDescriptor),
00429 USBGenericDescriptor_ENDPOINT,
00430 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT),
00431 USBEndpointDescriptor_BULK,
00432 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT),
00433 USBEndpointDescriptor_MAXBULKSIZE_FS),
00434 0x00
00435
00436 },
00437
00438
00439 {
00440 sizeof(USBEndpointDescriptor),
00441 USBGenericDescriptor_ENDPOINT,
00442 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_DATA_IN),
00443 USBEndpointDescriptor_BULK,
00444 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN),
00445 USBEndpointDescriptor_MAXBULKSIZE_FS),
00446 0x00
00447
00448 },
00449
00450
00451 {
00452 sizeof(USBEndpointDescriptor),
00453 USBGenericDescriptor_ENDPOINT,
00454 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION),
00455 USBEndpointDescriptor_INTERRUPT,
00456 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION),
00457 USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
00458 0x10
00459 }
00460 };
00461
00462
00463
00464 static const CCIDDriverConfigurationDescriptors sOtherSpeedConfigurationHS = {
00465
00466
00467
00468 {
00469 sizeof(USBConfigurationDescriptor),
00470 USBGenericDescriptor_OTHERSPEEDCONFIGURATION,
00471 sizeof(CCIDDriverConfigurationDescriptors),
00472 1,
00473 1,
00474 0,
00475 USBD_BMATTRIBUTES,
00476 USBConfigurationDescriptor_POWER(100)
00477 },
00478
00479
00480
00481 {
00482 sizeof(USBInterfaceDescriptor),
00483 USBGenericDescriptor_INTERFACE,
00484 0,
00485 0,
00486 3,
00487 SMART_CARD_DEVICE_CLASS,
00488 0,
00489 0,
00490 0
00491 },
00492 {
00493 sizeof(CCIDDescriptor),
00494 CCID_DECRIPTOR_TYPE,
00495 CCID1_10,
00496 0,
00497 VOLTS_5_0,
00498 PROTOCOL_TO,
00499 3580,
00500 3580,
00501 0,
00502 9600,
00503 9600,
00504 0,
00505 0xfe,
00506 0,
00507 0,
00508
00509 CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU,
00510 0x0000010F,
00511 0xFF,
00512 0xFF,
00513 0,
00514 0,
00515 1
00516 },
00517
00518 {
00519 sizeof(USBEndpointDescriptor),
00520 USBGenericDescriptor_ENDPOINT,
00521 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT),
00522 USBEndpointDescriptor_BULK,
00523 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT),
00524 USBEndpointDescriptor_MAXBULKSIZE_HS),
00525 0x00
00526
00527 },
00528
00529 {
00530 sizeof(USBEndpointDescriptor),
00531 USBGenericDescriptor_ENDPOINT,
00532 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_DATA_IN),
00533 USBEndpointDescriptor_BULK,
00534 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN),
00535 USBEndpointDescriptor_MAXBULKSIZE_HS),
00536 0x00
00537
00538 },
00539
00540 {
00541 sizeof(USBEndpointDescriptor),
00542 USBGenericDescriptor_ENDPOINT,
00543 USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION),
00544 USBEndpointDescriptor_INTERRUPT,
00545 MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION),
00546 USBEndpointDescriptor_MAXINTERRUPTSIZE_HS),
00547 0x10
00548 }
00549 };
00550 #endif
00551
00552
00553 static const unsigned char languageIdDescriptor[] = {
00554
00555 USBStringDescriptor_LENGTH(1),
00556 USBGenericDescriptor_STRING,
00557 USBStringDescriptor_ENGLISH_US
00558 };
00559
00560
00561 static const unsigned char manufacturerDescriptor[] = {
00562
00563 USBStringDescriptor_LENGTH(5),
00564 USBGenericDescriptor_STRING,
00565 USBStringDescriptor_UNICODE('A'),
00566 USBStringDescriptor_UNICODE('T'),
00567 USBStringDescriptor_UNICODE('M'),
00568 USBStringDescriptor_UNICODE('E'),
00569 USBStringDescriptor_UNICODE('L')
00570 };
00571
00572
00573 static const unsigned char productDescriptor[] = {
00574
00575 USBStringDescriptor_LENGTH(23),
00576 USBGenericDescriptor_STRING,
00577 USBStringDescriptor_UNICODE('A'),
00578 USBStringDescriptor_UNICODE('T'),
00579 USBStringDescriptor_UNICODE('M'),
00580 USBStringDescriptor_UNICODE('E'),
00581 USBStringDescriptor_UNICODE('L'),
00582 USBStringDescriptor_UNICODE(' '),
00583 USBStringDescriptor_UNICODE('A'),
00584 USBStringDescriptor_UNICODE('T'),
00585 USBStringDescriptor_UNICODE('9'),
00586 USBStringDescriptor_UNICODE('1'),
00587 USBStringDescriptor_UNICODE(' '),
00588 USBStringDescriptor_UNICODE('C'),
00589 USBStringDescriptor_UNICODE('C'),
00590 USBStringDescriptor_UNICODE('I'),
00591 USBStringDescriptor_UNICODE('D'),
00592 USBStringDescriptor_UNICODE(' '),
00593 USBStringDescriptor_UNICODE('D'),
00594 USBStringDescriptor_UNICODE('R'),
00595 USBStringDescriptor_UNICODE('I'),
00596 USBStringDescriptor_UNICODE('V'),
00597 USBStringDescriptor_UNICODE('E'),
00598 USBStringDescriptor_UNICODE('R'),
00599 USBStringDescriptor_UNICODE(' ')
00600 };
00601
00602
00603 static const unsigned char serialNumberDescriptor[] = {
00604
00605 USBStringDescriptor_LENGTH(12),
00606 USBGenericDescriptor_STRING,
00607 USBStringDescriptor_UNICODE('0'),
00608 USBStringDescriptor_UNICODE('1'),
00609 USBStringDescriptor_UNICODE('2'),
00610 USBStringDescriptor_UNICODE('3'),
00611 USBStringDescriptor_UNICODE('4'),
00612 USBStringDescriptor_UNICODE('5'),
00613 USBStringDescriptor_UNICODE('6'),
00614 USBStringDescriptor_UNICODE('7'),
00615 USBStringDescriptor_UNICODE('8'),
00616 USBStringDescriptor_UNICODE('9'),
00617 USBStringDescriptor_UNICODE('A'),
00618 USBStringDescriptor_UNICODE('F')
00619 };
00620
00621
00622 static const unsigned char *stringDescriptors[] = {
00623
00624 languageIdDescriptor,
00625 manufacturerDescriptor,
00626 productDescriptor,
00627 serialNumberDescriptor
00628 };
00629
00630
00631
00632 const USBDDriverDescriptors ccidDriverDescriptors = {
00633
00634 &deviceDescriptor,
00635
00636 (USBConfigurationDescriptor *) &configurationDescriptorsFS,
00637 #if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
00638 (USBDeviceQualifierDescriptor *) &deviceQualifierDescriptor,
00639 (USBConfigurationDescriptor *) &sOtherSpeedConfigurationFS,
00640 &deviceDescriptor,
00641 (USBConfigurationDescriptor *) &configurationDescriptorsHS,
00642 (USBDeviceQualifierDescriptor *) &deviceQualifierDescriptor,
00643
00644 (USBConfigurationDescriptor *) &sOtherSpeedConfigurationHS,
00645 #else
00646 0,
00647 0,
00648 0,
00649 0,
00650 0,
00651 0,
00652 #endif
00653 stringDescriptors,
00654 4
00655
00656 };
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 static void RDRtoPCSlotStatus(void)
00675 {
00676 TRACE_DEBUG("RDRtoPCSlotStatus\n\r");
00677
00678
00679
00680 ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_SLOTSTATUS;
00681 ccidDriver.sCcidMessage.wLength = 0;
00682 ccidDriver.sCcidMessage.bStatus = ccidDriver.SlotStatus;
00683 ccidDriver.sCcidMessage.bError = 0;
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 ccidDriver.sCcidMessage.bSpecific = 0;
00695 }
00696
00697
00698
00699
00700
00701 static void RDRtoPCDatablock_ATR(void)
00702 {
00703 unsigned char i;
00704 unsigned char Atr[ATR_SIZE_MAX];
00705 unsigned char length;
00706
00707
00708
00709
00710 ISO7816_Datablock_ATR(Atr, &length);
00711
00712 if (length > 5) {
00713 ccidDriver.ProtocolDataStructure[1] = Atr[5] & 0x0F;
00714
00715 ccidDriver.bProtocol = Atr[5] & 0x0F;
00716
00717 }
00718
00719
00720
00721
00722
00723 ccidDriver.ProtocolDataStructure[0] = Atr[2];
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 ccidDriver.ProtocolDataStructure[2] = Atr[4];
00740
00741
00742
00743
00744
00745
00746
00747
00748 ccidDriver.ProtocolDataStructure[3] = Atr[7];
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 ccidDriver.ProtocolDataStructure[4] = 0x00;
00764
00765
00766
00767
00768 ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_DATABLOCK;
00769 ccidDriver.sCcidMessage.wLength = length;
00770
00771 ccidDriver.sCcidMessage.bSizeToSend += length;
00772
00773
00774
00775 ccidDriver.sCcidMessage.bSpecific = 0;
00776
00777 for (i = 0; i < length; i++)
00778
00779 ccidDriver.sCcidMessage.abData[i] = Atr[i];
00780
00781
00782
00783 ccidDriver.sCcidMessage.bStatus = 0;
00784 ccidDriver.sCcidMessage.bError = 0;
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 static void RDRtoPCDatablock(void)
00798 {
00799
00800
00801
00802
00803
00804 ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_DATABLOCK;
00805 ccidDriver.sCcidMessage.bSizeToSend += ccidDriver.sCcidMessage.wLength;
00806
00807
00808 ccidDriver.sCcidMessage.bSpecific = 0;
00809
00810
00811
00812 ccidDriver.sCcidMessage.bStatus = 0;
00813 ccidDriver.sCcidMessage.bError = 0;
00814 }
00815
00816
00817
00818
00819
00820
00821
00822
00823 static void RDRtoPCParameters(void)
00824 {
00825 unsigned int i;
00826
00827 TRACE_DEBUG("RDRtoPCParameters\n\r");
00828
00829
00830
00831 ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_PARAMETERS;
00832
00833
00834
00835 ccidDriver.sCcidMessage.bError = 0;
00836
00837 if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_TO) {
00838
00839
00840
00841 ccidDriver.sCcidMessage.wLength = sizeof(S_ccid_protocol_t0);
00842 ccidDriver.sCcidMessage.bSpecific = PROTOCOL_TO;
00843 } else {
00844
00845
00846
00847 ccidDriver.sCcidMessage.wLength = sizeof(S_ccid_protocol_t1);
00848 ccidDriver.sCcidMessage.bSpecific = PROTOCOL_T1;
00849 }
00850
00851 ccidDriver.sCcidMessage.bSizeToSend += ccidDriver.sCcidMessage.wLength;
00852
00853 for (i = 0; i < ccidDriver.sCcidMessage.wLength; i++)
00854 ccidDriver.sCcidMessage.abData[i] = ccidDriver.ProtocolDataStructure[i];
00855
00856 }
00857
00858
00859
00860
00861
00862
00863 static void RDRtoPCEscape(unsigned char length,
00864 unsigned char *data_send_from_CCID)
00865 {
00866 unsigned int i;
00867
00868 TRACE_DEBUG("RDRtoPCEscape\n\r");
00869
00870
00871
00872 ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_ESCAPE;
00873
00874 ccidDriver.sCcidMessage.wLength = length;
00875
00876 ccidDriver.sCcidMessage.bStatus = 0;
00877 ccidDriver.sCcidMessage.bError = 0;
00878
00879 ccidDriver.sCcidMessage.bSpecific = 0;
00880
00881
00882 for (i = 0; i < length; i++)
00883 ccidDriver.sCcidMessage.abData[i] = data_send_from_CCID[i];
00884 }
00885
00886
00887
00888
00889
00890
00891 static void RDRtoPCDataRateAndClockFrequency(unsigned int dwClockFrequency,
00892 unsigned int dwDataRate)
00893 {
00894 TRACE_DEBUG("RDRtoPCDataRateAndClockFrequency\n\r");
00895
00896
00897
00898 ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_DATARATEANDCLOCKFREQUENCY;
00899
00900 ccidDriver.sCcidMessage.wLength = 8;
00901
00902 ccidDriver.sCcidMessage.bStatus = 0;
00903 ccidDriver.sCcidMessage.bError = 0;
00904
00905 ccidDriver.sCcidMessage.bSpecific = 0;
00906
00907
00908 ccidDriver.sCcidMessage.abData[0] = dwClockFrequency;
00909
00910 ccidDriver.sCcidMessage.abData[4] = dwDataRate;
00911 }
00912
00913
00914
00915
00916
00917
00918 static void PCtoRDRIccPowerOn(void)
00919 {
00920 TRACE_DEBUG("PCtoRDRIccPowerOn\n\r");
00921
00922 if (CCID_FEATURES_AUTO_VOLT == (configurationDescriptorsFS.ccid.dwFeatures &
00923 CCID_FEATURES_AUTO_VOLT)) {
00924
00925
00926
00927 ccidDriver.sCcidCommand.bSpecific_0 = VOLTS_AUTO;
00928 }
00929
00930 ISO7816_cold_reset();
00931
00932
00933
00934 if (ccidDriver.sCcidCommand.bSpecific_0 != VOLTS_5_0) {
00935
00936 TRACE_ERROR("POWER_NOT_SUPPORTED\n\r");
00937 }
00938 else
00939 RDRtoPCDatablock_ATR();
00940
00941 }
00942
00943
00944
00945
00946
00947
00948 static void PCtoRDRIccPowerOff(void)
00949 {
00950 unsigned char bStatus;
00951
00952 TRACE_DEBUG("PCtoRDRIccPowerOff\n\r");
00953
00954 ISO7816_IccPowerOff();
00955
00956
00957
00958 bStatus = ICC_BS_PRESENT_NOTACTIVATED;
00959
00960
00961
00962 ccidDriver.sCcidMessage.bStatus = 0;
00963 ccidDriver.sCcidMessage.bError = 0;
00964
00965
00966
00967
00968
00969
00970 RDRtoPCSlotStatus();
00971 }
00972
00973
00974
00975
00976
00977 static void PCtoRDRGetSlotStatus(void)
00978 {
00979 TRACE_DEBUG("PCtoRDRGetSlotStatus\n\r");
00980
00981 ccidDriver.sCcidMessage.bStatus = 0;
00982 ccidDriver.sCcidMessage.bError = 0;
00983
00984
00985
00986 RDRtoPCSlotStatus();
00987 }
00988
00989
00990
00991
00992
00993
00994 static void PCtoRDRXfrBlock(void)
00995 {
00996 unsigned char indexMessage = 0;
00997 unsigned char i;
00998
00999
01000
01001
01002 i = 0;
01003
01004
01005
01006 if (ccidDriver.sCcidCommand.wLength >
01007 (configurationDescriptorsFS.ccid.dwMaxCCIDMessageLength - 10)) {
01008
01009 ccidDriver.sCcidMessage.bStatus = 1;
01010 ccidDriver.sCcidMessage.bError = 0;
01011 }
01012
01013
01014 else if (0 != ccidDriver.sCcidCommand.bSpecific_0) {
01015 TRACE_ERROR("Bad bBWI\n\r");
01016 }
01017 else {
01018
01019
01020 switch (configurationDescriptorsFS.ccid.dwFeatures
01021 & (CCID_FEATURES_EXC_TPDU | CCID_FEATURES_EXC_SAPDU | CCID_FEATURES_EXC_APDU)) {
01022
01023 case CCID_FEATURES_EXC_TPDU:
01024 if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_TO) {
01025
01026
01027 indexMessage = ISO7816_XfrBlockTPDU_T0(ccidDriver.sCcidCommand.APDU ,
01028 ccidDriver.sCcidMessage.abData,
01029 ccidDriver.sCcidCommand.wLength);
01030 } else {
01031 if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_T1) {
01032 TRACE_INFO("Not supported T=1\n\r");
01033 }
01034 else {
01035 TRACE_INFO("Not supported\n\r");
01036 }
01037 }
01038
01039 break;
01040
01041 case CCID_FEATURES_EXC_APDU:
01042 TRACE_INFO("Not supported\n\r");
01043 break;
01044
01045 default:
01046 break;
01047 }
01048
01049 }
01050
01051 ccidDriver.sCcidMessage.wLength = indexMessage;
01052 TRACE_DEBUG("USB: 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n\r",
01053 ccidDriver.sCcidMessage.abData[0],
01054 ccidDriver.sCcidMessage.abData[1],
01055 ccidDriver.sCcidMessage.abData[2],
01056 ccidDriver.sCcidMessage.abData[3],
01057 ccidDriver.sCcidMessage.abData[4]);
01058 RDRtoPCDatablock();
01059
01060 }
01061
01062
01063
01064
01065
01066 static void PCtoRDRGetParameters(void)
01067 {
01068 TRACE_DEBUG("PCtoRDRGetParameters\n\r");
01069
01070
01071
01072
01073
01074
01075 if (ISO7816_StatusReset()) {
01076
01077
01078 ccidDriver.sCcidMessage.bStatus = 0;
01079 } else {
01080
01081
01082 ccidDriver.sCcidMessage.bStatus = 1;
01083 }
01084
01085 RDRtoPCParameters();
01086 }
01087
01088
01089
01090
01091
01092 static void PCtoRDRResetParameters(void)
01093 {
01094 TRACE_DEBUG("PCtoRDRResetParameters\n\r");
01095
01096 ccidDriver.SlotStatus = ICC_NOT_PRESENT;
01097 ccidDriver.sCcidMessage.bStatus = ccidDriver.SlotStatus;
01098
01099 RDRtoPCParameters();
01100 }
01101
01102
01103
01104
01105
01106 static void PCtoRDRSetParameters(void)
01107 {
01108 TRACE_DEBUG("PCtoRDRSetParameters\n\r");
01109
01110 ccidDriver.SlotStatus = ccidDriver.sCcidCommand.bSlot;
01111 ccidDriver.sCcidMessage.bStatus = ccidDriver.SlotStatus;
01112
01113
01114
01115 RDRtoPCParameters();
01116 }
01117
01118
01119
01120
01121
01122
01123
01124 static void PCtoRDREscape(void)
01125 {
01126 TRACE_DEBUG("PCtoRDREscape\n\r");
01127
01128
01129
01130 ISO7816_Escape();
01131
01132
01133
01134 RDRtoPCEscape(ccidDriver.sCcidCommand.wLength, ccidDriver.sCcidCommand.APDU);
01135 }
01136
01137
01138
01139
01140
01141 static void PCtoRDRICCClock(void)
01142 {
01143 TRACE_DEBUG("PCtoRDRICCClock\n\r");
01144
01145 if (0 == ccidDriver.sCcidCommand.bSpecific_0) {
01146
01147
01148 ISO7816_RestartClock();
01149 } else {
01150
01151
01152 ISO7816_StopClock();
01153 }
01154
01155 RDRtoPCSlotStatus();
01156 }
01157
01158
01159
01160
01161
01162
01163 static void PCtoRDRtoAPDU(void)
01164 {
01165 unsigned char bmChanges;
01166 unsigned char bClassGetResponse;
01167 unsigned char bClassEnvelope;
01168
01169 TRACE_DEBUG("PCtoRDRtoAPDU\n\r");
01170
01171 if (configurationDescriptorsFS.ccid.dwFeatures == (CCID_FEATURES_EXC_SAPDU |
01172 CCID_FEATURES_EXC_APDU)) {
01173
01174 bmChanges = ccidDriver.sCcidCommand.bSpecific_0;
01175 bClassGetResponse = ccidDriver.sCcidCommand.bSpecific_1;
01176 bClassEnvelope = ccidDriver.sCcidCommand.bSpecific_2;
01177
01178 ISO7816_toAPDU();
01179 }
01180
01181 RDRtoPCSlotStatus();
01182 }
01183
01184
01185
01186
01187
01188
01189 static void PCtoRDRSecure(void)
01190 {
01191 TRACE_DEBUG("PCtoRDRSecure\n\r");
01192
01193 TRACE_DEBUG("For user\n\r");
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204 static void PCtoRDRMechanical(void)
01205 {
01206 TRACE_DEBUG("PCtoRDRMechanical\n\r");
01207 TRACE_DEBUG("Not implemented\n\r");
01208
01209 RDRtoPCSlotStatus();
01210 }
01211
01212
01213
01214
01215
01216
01217
01218 static void PCtoRDRAbort(void)
01219 {
01220 TRACE_DEBUG("PCtoRDRAbort\n\r");
01221
01222 RDRtoPCSlotStatus();
01223 }
01224
01225
01226
01227
01228
01229
01230 static void PCtoRDRSetDataRateAndClockFrequency(void)
01231 {
01232 unsigned int dwClockFrequency;
01233 unsigned int dwDataRate;
01234
01235 TRACE_DEBUG("PCtoRDRSetDatarateandClockFrequency\n\r");
01236
01237 dwClockFrequency = ccidDriver.sCcidCommand.APDU[0]
01238 + (ccidDriver.sCcidCommand.APDU[1] << 8)
01239 + (ccidDriver.sCcidCommand.APDU[2] << 16)
01240 + (ccidDriver.sCcidCommand.APDU[3] << 24);
01241
01242 dwDataRate = ccidDriver.sCcidCommand.APDU[4]
01243 + (ccidDriver.sCcidCommand.APDU[5] << 8)
01244 + (ccidDriver.sCcidCommand.APDU[6] << 16)
01245 + (ccidDriver.sCcidCommand.APDU[7] << 24);
01246
01247 ISO7816_SetDataRateandClockFrequency(dwClockFrequency, dwDataRate);
01248
01249 RDRtoPCDataRateAndClockFrequency(dwClockFrequency, dwDataRate);
01250
01251 }
01252
01253
01254
01255
01256 static void vCCIDCommandNotSupported(void)
01257 {
01258
01259
01260
01261
01262
01263 TRACE_DEBUG("CMD_NOT_SUPPORTED\n\r");
01264
01265
01266
01267 ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_SLOTSTATUS;
01268 ccidDriver.sCcidMessage.wLength = 0;
01269 ccidDriver.sCcidMessage.bSpecific = 0;
01270
01271 ccidDriver.sCcidMessage.bStatus |= ICC_CS_FAILED;
01272
01273
01274
01275
01276
01277 }
01278
01279
01280
01281
01282 static void vCCIDSendResponse(void)
01283 {
01284 unsigned char bStatus;
01285
01286 do {
01287 bStatus = USBD_Write(CCID_EPT_DATA_IN, (void *)&ccidDriver.sCcidMessage,
01288 ccidDriver.sCcidMessage.bSizeToSend, 0, 0);
01289 } while (bStatus != USBD_STATUS_SUCCESS);
01290 }
01291
01292
01293
01294
01295
01296 static void CCIDCommandDispatcher(void)
01297 {
01298 unsigned char MessageToSend = 0;
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319 if (ccidDriver.sCcidCommand.bSlot > 0) {
01320 TRACE_ERROR("BAD_SLOT_NUMBER\n\r");
01321 }
01322
01323 TRACE_DEBUG("typ=0x%X\n\r", ccidDriver.sCcidCommand.bMessageType);
01324
01325 ccidDriver.sCcidMessage.bStatus = 0;
01326
01327 ccidDriver.sCcidMessage.bSeq = ccidDriver.sCcidCommand.bSeq;
01328 ccidDriver.sCcidMessage.bSlot = ccidDriver.sCcidCommand.bSlot;
01329
01330 ccidDriver.sCcidMessage.bSizeToSend = sizeof(S_ccid_bulk_in_header) -
01331 (ABDATA_SIZE + 1);
01332
01333
01334
01335
01336 switch (ccidDriver.sCcidCommand.bMessageType) {
01337
01338 case PC_TO_RDR_ICCPOWERON:
01339 PCtoRDRIccPowerOn();
01340 MessageToSend = 1;
01341 break;
01342
01343 case PC_TO_RDR_ICCPOWEROFF:
01344 PCtoRDRIccPowerOff();
01345 MessageToSend = 1;
01346 break;
01347
01348 case PC_TO_RDR_GETSLOTSTATUS:
01349 PCtoRDRGetSlotStatus();
01350 MessageToSend = 1;
01351 break;
01352
01353 case PC_TO_RDR_XFRBLOCK:
01354 PCtoRDRXfrBlock();
01355 MessageToSend = 1;
01356 break;
01357
01358 case PC_TO_RDR_GETPARAMETERS:
01359 PCtoRDRGetParameters();
01360 MessageToSend = 1;
01361 break;
01362
01363 case PC_TO_RDR_RESETPARAMETERS:
01364 PCtoRDRResetParameters();
01365 MessageToSend = 1;
01366 break;
01367
01368 case PC_TO_RDR_SETPARAMETERS:
01369 PCtoRDRSetParameters();
01370 MessageToSend = 1;
01371 break;
01372
01373 case PC_TO_RDR_ESCAPE:
01374 PCtoRDREscape();
01375 MessageToSend = 1;
01376 break;
01377
01378 case PC_TO_RDR_ICCCLOCK:
01379 PCtoRDRICCClock();
01380 MessageToSend = 1;
01381 break;
01382
01383 case PC_TO_RDR_T0APDU:
01384
01385
01386
01387
01388
01389 if ((CCID_FEATURES_EXC_SAPDU == (CCID_FEATURES_EXC_SAPDU &
01390 configurationDescriptorsFS.ccid.dwFeatures))
01391 || (CCID_FEATURES_EXC_APDU == (CCID_FEATURES_EXC_APDU &
01392 configurationDescriptorsFS.ccid.dwFeatures))) {
01393
01394
01395
01396 PCtoRDRtoAPDU();
01397 } else {
01398
01399
01400 TRACE_DEBUG("PC_TO_RDR_T0APDU\n\r");
01401 vCCIDCommandNotSupported();
01402 }
01403
01404 MessageToSend = 1;
01405 break;
01406
01407 case PC_TO_RDR_SECURE:
01408 PCtoRDRSecure();
01409 MessageToSend = 1;
01410 break;
01411
01412 case PC_TO_RDR_MECHANICAL:
01413 PCtoRDRMechanical();
01414 MessageToSend = 1;
01415 break;
01416
01417 case PC_TO_RDR_ABORT:
01418 PCtoRDRAbort();
01419 MessageToSend = 1;
01420 break;
01421
01422 case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY:
01423 PCtoRDRSetDataRateAndClockFrequency();
01424 MessageToSend = 1;
01425 break;
01426
01427 default:
01428 TRACE_DEBUG("default: 0x%X\n\r", ccidDriver.sCcidCommand.bMessageType);
01429 vCCIDCommandNotSupported();
01430 MessageToSend = 1;
01431 break;
01432
01433 }
01434
01435 if (MessageToSend == 1)
01436 vCCIDSendResponse();
01437 }
01438
01439
01440
01441
01442
01443
01444 static void CCID_RequestHandler(const USBGenericRequest *pRequest)
01445 {
01446 TRACE_DEBUG("CCID_RHl\n\r");
01447
01448
01449
01450 if (USBGenericRequest_GetType(pRequest) == USBGenericRequest_CLASS) {
01451
01452
01453
01454 switch (USBGenericRequest_GetRequest(pRequest)) {
01455
01456 case CCIDGenericRequest_ABORT:
01457 TRACE_DEBUG("CCIDGenericRequest_ABORT\n\r");
01458 break;
01459
01460 case CCIDGenericRequest_GET_CLOCK_FREQUENCIES:
01461 TRACE_DEBUG("Not supported\n\r");
01462
01463
01464
01465
01466 break;
01467
01468 case CCIDGenericRequest_GET_DATA_RATES:
01469 TRACE_DEBUG("Not supported\n\r");
01470
01471
01472
01473
01474 break;
01475
01476 default:
01477 TRACE_WARNING("CCIDDriver_RequestHandler: Unsupported request (%d)\n\r",
01478 USBGenericRequest_GetRequest(pRequest));
01479 USBD_Stall(0);
01480 }
01481 }
01482
01483 else if (USBGenericRequest_GetType(pRequest) == USBGenericRequest_STANDARD) {
01484
01485
01486
01487 USBDDriver_RequestHandler(&(ccidDriver.usbdDriver), pRequest);
01488 } else {
01489
01490
01491 TRACE_WARNING("CCIDDriver_RequestHandler: Unsupported request type (%d)\n\r",
01492 USBGenericRequest_GetType(pRequest));
01493 USBD_Stall(0);
01494 }
01495 }
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505 #if !defined(NOAUTOCALLBACK)
01506
01507
01508 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
01509 {
01510 CCID_RequestHandler(request);
01511 }
01512 #endif
01513
01514
01515
01516
01517
01518 void CCID_SmartCardRequest(void)
01519 {
01520 unsigned char bStatus;
01521
01522 do {
01523
01524 bStatus = CCID_Read((void *)&ccidDriver.sCcidCommand,
01525 sizeof(S_ccid_bulk_out_header),
01526 (TransferCallback)&CCIDCommandDispatcher,
01527 (void *)0);
01528 } while (bStatus != USBD_STATUS_SUCCESS);
01529
01530 }
01531
01532
01533
01534
01535 void CCIDDriver_Initialize(void)
01536 {
01537 TRACE_DEBUG("CCID_Init\n\r");
01538 USBDDriver_Initialize(&(ccidDriver.usbdDriver),
01539 &ccidDriverDescriptors,
01540 0);
01541
01542 USBD_Init();
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553 unsigned char CCID_Read(void *pBuffer,
01554 unsigned int dLength,
01555 TransferCallback fCallback,
01556 void *pArgument)
01557 {
01558 return USBD_Read(CCID_EPT_DATA_OUT, pBuffer, dLength, fCallback, pArgument);
01559 }
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 unsigned char CCID_Write(void *pBuffer,
01570 unsigned int dLength,
01571 TransferCallback fCallback,
01572 void *pArgument)
01573 {
01574 return USBD_Write(CCID_EPT_DATA_IN, pBuffer, dLength, fCallback, pArgument);
01575 }
01576
01577
01578
01579
01580
01581
01582 unsigned char CCID_Insertion(void)
01583 {
01584 TRACE_DEBUG("CCID_Insertion\n\r");
01585
01586
01587
01588 ccidDriver.BufferINT[0] = RDR_TO_PC_NOTIFYSLOTCHANGE;
01589 ccidDriver.BufferINT[1] = ICC_INSERTED_EVENT;
01590 ccidDriver.SlotStatus = ICC_INSERTED_EVENT;
01591
01592
01593
01594 return USBD_Write(CCID_EPT_NOTIFICATION, ccidDriver.BufferINT, 2, 0, 0);
01595 }
01596
01597
01598
01599
01600
01601
01602 unsigned char CCID_Removal(void)
01603 {
01604 TRACE_DEBUG("CCID_Removal\n\r");
01605
01606
01607
01608 ccidDriver.BufferINT[0] = RDR_TO_PC_NOTIFYSLOTCHANGE;
01609 ccidDriver.BufferINT[1] = ICC_NOT_PRESENT;
01610 ccidDriver.SlotStatus = ICC_NOT_PRESENT;
01611
01612
01613
01614 return USBD_Write(CCID_EPT_NOTIFICATION, ccidDriver.BufferINT, 2, 0, 0);
01615 }
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628 unsigned char RDRtoPCHardwareError(unsigned char bSlot,
01629 unsigned char bSeq,
01630 unsigned char bHardwareErrorCode)
01631 {
01632 TRACE_DEBUG("RDRtoPCHardwareError\n\r");
01633
01634
01635
01636 ccidDriver.BufferINT[0] = RDR_TO_PC_HARDWAREERROR;
01637 ccidDriver.BufferINT[1] = bSlot;
01638 ccidDriver.BufferINT[2] = bSeq;
01639 ccidDriver.BufferINT[3] = bHardwareErrorCode;
01640
01641
01642
01643 return USBD_Write(CCID_EPT_NOTIFICATION, ccidDriver.BufferINT, 4, 0, 0);
01644 }
01645
01646
01647