From 87c0882297ccdc41b1db63af240166904c6a7539 Mon Sep 17 00:00:00 2001 From: Filipe Paz Rodrigues Date: Wed, 10 May 2023 22:47:24 -0700 Subject: [PATCH 1/7] Add USB_DTYPE_FUNCTIONAL_DESC constant --- inc/usb_std.h | 1 + 1 file changed, 1 insertion(+) diff --git a/inc/usb_std.h b/inc/usb_std.h index 6cb8ba4..ce2e3e1 100644 --- a/inc/usb_std.h +++ b/inc/usb_std.h @@ -126,6 +126,7 @@ extern "C" { #define USB_DTYPE_OTG 0x09 /**<\brief OTG descriptor.*/ #define USB_DTYPE_DEBUG 0x0A /**<\brief Debug descriptor.*/ #define USB_DTYPE_INTERFASEASSOC 0x0B /**<\brief Interface association descriptor.*/ +#define USB_DTYPE_FUNCTIONAL_DESC 0x21 /**<\brief Functonal descriptor.*/ #define USB_DTYPE_CS_INTERFACE 0x24 /**<\brief Class specific interface descriptor.*/ #define USB_DTYPE_CS_ENDPOINT 0x25 /**<\brief Class specific endpoint descriptor.*/ /** @} */ From 5d0c2d33a52403471e4227a7f7dba24c98f4dce6 Mon Sep 17 00:00:00 2001 From: Filipe Paz Rodrigues Date: Wed, 10 May 2023 22:56:30 -0700 Subject: [PATCH 2/7] Add CCID support --- inc/usb_ccid.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 inc/usb_ccid.h diff --git a/inc/usb_ccid.h b/inc/usb_ccid.h new file mode 100644 index 0000000..c96fd5d --- /dev/null +++ b/inc/usb_ccid.h @@ -0,0 +1,79 @@ +#include + +#ifndef _USB_CCID_H_ +#define _USB_CCID_H_ +#ifdef __cplusplus + extern "C" { +#endif + +#define USB_CLASS_CCID 0x0b /**<\brief Communicational Device class */ +#define USB_DTYPE_FUNCTIONAL_DESC 0x21 /**<\brief Functonal descriptor.*/ + +#define ENDPOINT_DIR_IN 0x80 +#define ENDPOINT_DIR_OUT 0x00 + +#define INTERFACE_ID_CCID 0 + +#define CCID_IN_EPADDR (ENDPOINT_DIR_IN | 2) + +/** Endpoint address of the CCID data OUT endpoint, for host-to-device data transfers. */ +#define CCID_OUT_EPADDR (ENDPOINT_DIR_OUT | 1) + +/** Endpoint size in bytes of the CCID data being sent between IN and OUT endpoints. */ +#define CCID_EPSIZE 64 + + +#define CCID_CURRENT_SPEC_RELEASE_NUMBER 0x0110 +#define CCID_VOLTAGESUPPORT_5V 0 +#define CCID_VOLTAGESUPPORT_3V (1 << 0) +#define CCID_VOLTAGESUPPORT_1V8 (1 << 1) + +#define CCID_PROTOCOL_T0 0 +#define CCID_PROTOCOL_T1 (1 << 0) + +#define CCID_ICCSTATUS_PRESENTANDACTIVE 0 +#define CCID_ICCSTATUS_PRESENTANDINACTIVE (1 << 0) +#define CCID_ICCSTATUS_NOICCPRESENT (1 << 1) + +#define CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR 0 +#define CCID_COMMANDSTATUS_FAILED (1 << 6) +#define CCID_COMMANDSTATUS_TIMEEXTENSIONREQUESTED (1 << 7) + +#define CCID_ERROR_NOERROR 0 +#define CCID_ERROR_SLOTNOTFOUND 5 + +#define CCID_ABORT 0x1 +#define CCID_GET_CLOCK_FREQUENCIES 0x2 +#define CCID_GET_DATA_RATES 0x3 + +struct usb_ccid_descriptor { + uint8_t bLength; /**<\brief Size of the descriptor, in bytes.*/ + uint8_t bDescriptorType; /**<\brief IAD descriptor */ + + uint16_t CCID; + uint8_t MaxSlotIndex; + uint8_t VoltageSupport; + uint32_t Protocols; + uint32_t DefaultClock; + uint32_t MaximumClock; + uint8_t NumClockSupported; + uint32_t DataRate; + uint32_t MaxDataRate; + uint8_t NumDataRatesSupported; + uint32_t MaxIFSD; + uint32_t SynchProtocols; + uint32_t Mechanical; + uint32_t Features; + uint32_t MaxCCIDMessageLength; + uint8_t ClassGetResponse; + uint8_t ClassEnvelope; + uint16_t LcdLayout; + uint8_t PINSupport; + uint8_t MaxCCIDBusySlots; +} __attribute__((packed)); + +#ifdef __cplusplus + } +#endif + +#endif From 3f6e733bdac644250379291b8818101b56729427 Mon Sep 17 00:00:00 2001 From: Filipe Paz Rodrigues Date: Tue, 27 Jun 2023 14:32:22 -0700 Subject: [PATCH 3/7] Update usb_std.h --- inc/usb_std.h | 1 - 1 file changed, 1 deletion(-) diff --git a/inc/usb_std.h b/inc/usb_std.h index ce2e3e1..6cb8ba4 100644 --- a/inc/usb_std.h +++ b/inc/usb_std.h @@ -126,7 +126,6 @@ extern "C" { #define USB_DTYPE_OTG 0x09 /**<\brief OTG descriptor.*/ #define USB_DTYPE_DEBUG 0x0A /**<\brief Debug descriptor.*/ #define USB_DTYPE_INTERFASEASSOC 0x0B /**<\brief Interface association descriptor.*/ -#define USB_DTYPE_FUNCTIONAL_DESC 0x21 /**<\brief Functonal descriptor.*/ #define USB_DTYPE_CS_INTERFACE 0x24 /**<\brief Class specific interface descriptor.*/ #define USB_DTYPE_CS_ENDPOINT 0x25 /**<\brief Class specific endpoint descriptor.*/ /** @} */ From 3cf84fbb2d97c699041f4954c3eb85d9882084fc Mon Sep 17 00:00:00 2001 From: Filipe Paz Rodrigues Date: Tue, 27 Jun 2023 14:35:57 -0700 Subject: [PATCH 4/7] Update usb_ccid.h --- inc/usb_ccid.h | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/inc/usb_ccid.h b/inc/usb_ccid.h index c96fd5d..923cd75 100644 --- a/inc/usb_ccid.h +++ b/inc/usb_ccid.h @@ -6,23 +6,15 @@ extern "C" { #endif -#define USB_CLASS_CCID 0x0b /**<\brief Communicational Device class */ -#define USB_DTYPE_FUNCTIONAL_DESC 0x21 /**<\brief Functonal descriptor.*/ - -#define ENDPOINT_DIR_IN 0x80 -#define ENDPOINT_DIR_OUT 0x00 - -#define INTERFACE_ID_CCID 0 - -#define CCID_IN_EPADDR (ENDPOINT_DIR_IN | 2) - -/** Endpoint address of the CCID data OUT endpoint, for host-to-device data transfers. */ -#define CCID_OUT_EPADDR (ENDPOINT_DIR_OUT | 1) +#define USB_CLASS_CCID 0x0b /**<\brief Smart Card Device class */ +#define USB_DTYPE_FUNCTIONAL_DESC 0x21 /**<\brief Funcitonal descriptor.*/ +#define USB_DTYPE_CCID_FUNCTIONAL 0x21 /**<\brief Functional descriptor.*/ /** Endpoint size in bytes of the CCID data being sent between IN and OUT endpoints. */ #define CCID_EPSIZE 64 + #define CCID_CURRENT_SPEC_RELEASE_NUMBER 0x0110 #define CCID_VOLTAGESUPPORT_5V 0 #define CCID_VOLTAGESUPPORT_3V (1 << 0) From 0f0a1e73880298c132c8e16006288b2f6acda108 Mon Sep 17 00:00:00 2001 From: Filipe Paz Rodrigues Date: Thu, 29 Jun 2023 11:43:33 -0700 Subject: [PATCH 5/7] Update usb_ccid.h --- inc/usb_ccid.h | 61 +++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/inc/usb_ccid.h b/inc/usb_ccid.h index 923cd75..021d066 100644 --- a/inc/usb_ccid.h +++ b/inc/usb_ccid.h @@ -1,3 +1,18 @@ +/* This file is the part of the Lightweight USB device Stack for STM32 microcontrollers + * Reference: https://www.usb.org/sites/default/files/DWG_Smart-Card_CCID_Rev110.pdf + * + * Copyright ©2023 Filipe Rodrigues + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #ifndef _USB_CCID_H_ @@ -7,14 +22,8 @@ #endif #define USB_CLASS_CCID 0x0b /**<\brief Smart Card Device class */ -#define USB_DTYPE_FUNCTIONAL_DESC 0x21 /**<\brief Funcitonal descriptor.*/ #define USB_DTYPE_CCID_FUNCTIONAL 0x21 /**<\brief Functional descriptor.*/ -/** Endpoint size in bytes of the CCID data being sent between IN and OUT endpoints. */ -#define CCID_EPSIZE 64 - - - #define CCID_CURRENT_SPEC_RELEASE_NUMBER 0x0110 #define CCID_VOLTAGESUPPORT_5V 0 #define CCID_VOLTAGESUPPORT_3V (1 << 0) @@ -42,26 +51,26 @@ struct usb_ccid_descriptor { uint8_t bLength; /**<\brief Size of the descriptor, in bytes.*/ uint8_t bDescriptorType; /**<\brief IAD descriptor */ - uint16_t CCID; - uint8_t MaxSlotIndex; - uint8_t VoltageSupport; - uint32_t Protocols; - uint32_t DefaultClock; - uint32_t MaximumClock; - uint8_t NumClockSupported; - uint32_t DataRate; - uint32_t MaxDataRate; - uint8_t NumDataRatesSupported; - uint32_t MaxIFSD; - uint32_t SynchProtocols; - uint32_t Mechanical; - uint32_t Features; - uint32_t MaxCCIDMessageLength; - uint8_t ClassGetResponse; - uint8_t ClassEnvelope; - uint16_t LcdLayout; - uint8_t PINSupport; - uint8_t MaxCCIDBusySlots; + uint16_t bcdCCID; + uint8_t bMaxSlotIndex; + uint8_t bVoltageSupport; + uint32_t dwProtocols; + uint32_t dwDefaultClock; + uint32_t dwMaximumClock; + uint8_t bNumClockSupported; + uint32_t dwDataRate; + uint32_t dwMaxDataRate; + uint8_t bNumDataRatesSupported; + uint32_t dwMaxIFSD; + uint32_t dwSynchProtocols; + uint32_t dwMechanical; + uint32_t dwFeatures; + uint32_t dwMaxCCIDMessageLength; + uint8_t bClassGetResponse; + uint8_t bClassEnvelope; + uint16_t wLcdLayout; + uint8_t bPINSupport; + uint8_t bMaxCCIDBusySlots; } __attribute__((packed)); #ifdef __cplusplus From a089062ba9b789aca50ff10450b0f21a64d136d4 Mon Sep 17 00:00:00 2001 From: Filipe Paz Rodrigues Date: Thu, 29 Jun 2023 12:36:09 -0700 Subject: [PATCH 6/7] Update usb_ccid.h --- inc/usb_ccid.h | 282 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) diff --git a/inc/usb_ccid.h b/inc/usb_ccid.h index 021d066..c288ad3 100644 --- a/inc/usb_ccid.h +++ b/inc/usb_ccid.h @@ -47,6 +47,34 @@ #define CCID_GET_CLOCK_FREQUENCIES 0x2 #define CCID_GET_DATA_RATES 0x3 +/* Bulk-OUT Messages */ +#define PC_TO_RDR_ICCPOWERON 0x62 +#define PC_TO_RDR_ICCPOWEROFF 0x63 +#define PC_TO_RDR_GETSLOTSTATUS 0x65 +#define PC_TO_RDR_XFRBLOCK 0x6F +#define PC_TO_RDR_GETPARAMETERS 0x6C +#define PC_TO_RDR_RESETPARAMETERS 0x6D +#define PC_TO_RDR_SETPARAMETERS 0x61 +#define PC_TO_RDR_ESCAPE 0x6B +#define PC_TO_RDR_ICCCLOCK 0x6E +#define PC_TO_RDR_T0APDU 0x6A +#define PC_TO_RDR_SECURE 0x69 +#define PC_TO_RDR_MECHANICAL 0x71 +#define PC_TO_RDR_ABORT 0x72 +#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73 + +/* Bulk-IN Messages */ +#define RDR_TO_PC_DATABLOCK 0x80 +#define RDR_TO_PC_SLOTSTATUS 0x81 +#define RDR_TO_PC_PARAMETERS 0x82 +#define RDR_TO_PC_ESCAPE 0x83 +#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84 + +/* Interrupt-IN Messages */ +#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50 +#define RDR_TO_PC_HARDWAREERROR 0x51 + + struct usb_ccid_descriptor { uint8_t bLength; /**<\brief Size of the descriptor, in bytes.*/ uint8_t bDescriptorType; /**<\brief IAD descriptor */ @@ -73,6 +101,260 @@ struct usb_ccid_descriptor { uint8_t bMaxCCIDBusySlots; } __attribute__((packed)); + +/* Bulk-Out Messages*/ + +struct PC_to_RDR_IccPowerOn { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bPowerSelect; + uint8_t abRFU[2]; +} __attribute__((packed)); + +struct PC_to_RDR_IccPowerOff { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t abRFU[3]; +} __attribute__((packed)); + +struct PC_to_RDR_GetSlotStatus { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t abRFU[3]; +} __attribute__((packed)); + +struct PC_to_RDR_XfrBlock { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bSeq; + uint8_t bBWI; + uint16_t wLevelParameter; + uint8_t abData[0]; +} __attribute__((packed)); + +struct PC_to_RDR_GetParameters { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t abRFU[3]; +} __attribute__((packed)); + +struct PC_to_RDR_ResetParameters { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t abRFU[3]; +} __attribute__((packed)); + +struct PC_to_RDR_SetParameters_T0 { + //common + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bProtocolNum; + uint8_t abRFU[2]; + + //specific for T=0 + uint8_t bmFindexDindex; + uint8_t bmTCCKST0; + uint8_t bGuardTimeT0; + uint8_t bWaitingIntegerT0; + uint8_t bClockStop; +} __attribute__((packed)); + +struct PC_to_RDR_SetParameters_T1 { + //common + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bProtocolNum; + uint8_t abRFU[2]; + + //specific for T=1 + uint8_t bmFindexDindex; + uint8_t bmTCCKST1; + uint8_t bGuardTimeT1; + uint8_t bmWaitingIntegersT1; + uint8_t bClockStop; + uint8_t bIFSC; + uint8_t bNadValue; +} __attribute__((packed)); + +struct PC_to_RDR_Escape { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t abRFU[3]; + uint8_t abData[0]; +} __attribute__((packed)); + +struct PC_to_RDR_IccClock { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bClockCommand; + uint8_t abRFU[2]; +} __attribute__((packed)); + +struct PC_to_RDR_T0APDU { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bmChanges; + uint8_t bClassGetResponse; + uint8_t bClassEnvelope; +} __attribute__((packed)); + +struct PC_to_RDR_Secure { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bBWI; + uint16_t wLevelParameter; + uint8_t abData[0]; +} __attribute__((packed)); + +struct PC_to_RDR_Mechanical { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bFunction; + uint8_t abRFU[2]; +} __attribute__((packed)); + +struct PC_to_RDR_Abort { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t abRFU[3]; +} __attribute__((packed)); + +struct PC_to_RDR_SetDataRateAndClockFrequency { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t abRFU[3]; + uint32_t dwClockFrequency; + uint32_t dwDataRate; +} __attribute__((packed)); + +/* Bulk-In Messages*/ + +struct RDR_to_PC_DataBlock { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bStatus; + uint8_t bError; + uint8_t bChainParameter; + uint8_t abData[0]; +} __attribute__((packed)); + +struct RDR_to_PC_SlotStatus { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bStatus; + uint8_t bError; + uint8_t bClockStatus; +} __attribute__((packed)); + +struct RDR_to_PC_Parameters_T0 { + //common + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bStatus; + uint8_t bError; + uint8_t bProtocolNum; + + //specific for T=0 + uint8_t bmFindexDindex; + uint8_t bmTCCKST0; + uint8_t bGuardTimeT0; + uint8_t bWaitingIntegerT0; + uint8_t bClockStop; +} __attribute__((packed)); + +struct RDR_to_PC_Parameters_T1 { + //common + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bStatus; + uint8_t bError; + uint8_t bProtocolNum; + + //specific for T=1 + uint8_t bmFindexDindex; + uint8_t bmTCCKST1; + uint8_t bGuardTimeT1; + uint8_t bmWaitingIntegersT1; + uint8_t bClockStop; + uint8_t bIFSC; + uint8_t bNadValue; +} __attribute__((packed)); + +struct RDR_to_PC_Escape { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bStatus; + uint8_t bError; + uint8_t bRFU; + uint8_t abData[0]; +} __attribute__((packed)); + +struct RDR_to_PC_DataRateAndClockFrequency { + uint8_t bMessageType; + uint32_t dwLength; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bStatus; + uint8_t bError; + uint8_t bRFU; + uint32_t dwClockFrequency; + uint32_t dwDataRate; +} __attribute__((packed)); + +/* Interrupt-In Messages*/ + +struct RDR_to_PC_NotifySlotChange { + uint8_t bMessageType; + uint8_t bmSlotICCState[0]; +} __attribute__((packed)); + +struct RDR_to_PC_NotifySlotChange { + uint8_t bMessageType; + uint8_t bSlot; + uint8_t bSeq; + uint8_t bHardwareErrorCode; +} __attribute__((packed)); + #ifdef __cplusplus } #endif From d2efb45bb4471fd2709f89c1cc9dce050f77a230 Mon Sep 17 00:00:00 2001 From: Filipe Paz Rodrigues Date: Wed, 5 Jul 2023 23:30:47 -0700 Subject: [PATCH 7/7] Update usb_ccid.h --- inc/usb_ccid.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/inc/usb_ccid.h b/inc/usb_ccid.h index c288ad3..2ee4188 100644 --- a/inc/usb_ccid.h +++ b/inc/usb_ccid.h @@ -134,7 +134,6 @@ struct PC_to_RDR_XfrBlock { uint32_t dwLength; uint8_t bSlot; uint8_t bSeq; - uint8_t bSeq; uint8_t bBWI; uint16_t wLevelParameter; uint8_t abData[0]; @@ -348,7 +347,7 @@ struct RDR_to_PC_NotifySlotChange { uint8_t bmSlotICCState[0]; } __attribute__((packed)); -struct RDR_to_PC_NotifySlotChange { +struct RDR_to_PC_HardwareError { uint8_t bMessageType; uint8_t bSlot; uint8_t bSeq;