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