From fc371d0d0e3a60b06dec862e37612375860c41d5 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Sun, 17 Jun 2018 14:21:45 +1000 Subject: Add CCID class driver and associated demos. --- LUFA/Build/LUFA/lufa-sources.mk | 1 + LUFA/DoxygenPages/ChangeLog.txt | 1 + LUFA/DoxygenPages/VIDAndPIDValues.txt | 2 +- LUFA/Drivers/USB/Class/CCIDClass.h | 83 +++++++ LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h | 269 ++++++++++++++++++++ LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c | 316 ++++++++++++++++++++++++ LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h | 127 ++++++++++ LUFA/Drivers/USB/USB.h | 1 + 8 files changed, 799 insertions(+), 1 deletion(-) create mode 100644 LUFA/Drivers/USB/Class/CCIDClass.h create mode 100644 LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h create mode 100644 LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c create mode 100644 LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h (limited to 'LUFA') diff --git a/LUFA/Build/LUFA/lufa-sources.mk b/LUFA/Build/LUFA/lufa-sources.mk index b18be5388..296599dd5 100644 --- a/LUFA/Build/LUFA/lufa-sources.mk +++ b/LUFA/Build/LUFA/lufa-sources.mk @@ -55,6 +55,7 @@ LUFA_SRC_USB_DEVICE := $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Device_$( $(LUFA_SRC_USB_COMMON) LUFA_SRC_USBCLASS_DEVICE := $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/AudioClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/CCIDClassDevice.c \ $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/CDCClassDevice.c \ $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/HIDClassDevice.c \ $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MassStorageClassDevice.c \ diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt index e1424c5f9..228e236aa 100644 --- a/LUFA/DoxygenPages/ChangeLog.txt +++ b/LUFA/DoxygenPages/ChangeLog.txt @@ -10,6 +10,7 @@ * New: * - Core: * - The USE_INTERNAL_SERIAL definition can now be overridden by the user to a custom string index (thanks to Nicohood) + * - New CCID class driver and associated demos (thanks to Filipe Rodrigues) * - Library Applications: * - Added Microsoft OS Compatibility descriptors to the RNDIS demos for driverless install on Windows 7 and newer * diff --git a/LUFA/DoxygenPages/VIDAndPIDValues.txt b/LUFA/DoxygenPages/VIDAndPIDValues.txt index 8b1722044..8f62486f7 100644 --- a/LUFA/DoxygenPages/VIDAndPIDValues.txt +++ b/LUFA/DoxygenPages/VIDAndPIDValues.txt @@ -181,7 +181,7 @@ * * 0x03EB * 0x206E - * Currently Unallocated + * CCID Class Demo Application * * * 0x03EB diff --git a/LUFA/Drivers/USB/Class/CCIDClass.h b/LUFA/Drivers/USB/Class/CCIDClass.h new file mode 100644 index 000000000..681326f65 --- /dev/null +++ b/LUFA/Drivers/USB/Class/CCIDClass.h @@ -0,0 +1,83 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2018. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2018 Filipe Rodrigues (filipepazrodrigues [at] gmail [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB CCID Class driver. + * + * Master include file for the library USB CCID Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassCCID CCID Class Driver + * \brief USB class driver for the USB-IF CCID class standard. + * + * \section Sec_USBClassCCID_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/CCIDClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_USBClassCCID_ModDescription Module Description + * CCID Class Driver module. This module contains an internal implementation of the USB CCID Class, for both Device + * and Host USB modes. User applications can use this class driver instead of implementing the CCID class manually + * via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Hosts or Devices using the USB CCID Class. + * + * \warning + * LUFA is not a secure USB stack, and has not undergone, not is it expected to pass, any form of security audit. The + * CCID class here is presented as-is and is intended for research purposes only, and *should not* be used in a security + * critical application under any circumstances. + * + * @{ + */ + +#ifndef _CCID_CLASS_H_ +#define _CCID_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_CCID_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "Device/CCIDClassDevice.h" + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h new file mode 100644 index 000000000..61239ec8a --- /dev/null +++ b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h @@ -0,0 +1,269 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2018. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2018 Filipe Rodrigues (filipepazrodrigues [at] gmail [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB CCID Class driver. + * + * Common definitions and declarations for the library USB CCID Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassCCID + * \defgroup Group_USBClassCCIDCommon Common Class Definitions + * + * \section Sec_USBClassCCIDCommon_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * CCID Class. + * + * @{ + */ + +#ifndef _CCID_CLASS_COMMON_H_ +#define _CCID_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_CCID_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + #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_PROTOCOLS_T0 (1 << 0) + #define CCID_PROTOCOLS_T1 (1 << 1) + + #define CCID_PROTOCOLNUM_T0 0 + #define CCID_PROTOCOLNUM_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 (2 << 6) + #define CCID_COMMANDSTATUS_RFU (3 << 6) + + #define CCID_ERROR_RFU_START 0x80 + #define CCID_ERROR_NO_ERROR 0x80 + #define CCID_ERROR_NOT_SUPPORTED 0 + #define CCID_ERROR_CMD_ABORTED 0xFF + #define CCID_ERROR_CMD_NOT_ABORTED 0xFF + + #define CCID_ERROR_SLOT_NOT_FOUND 5 + + #define CCID_DESCRIPTOR_CLOCK_KHZ(khz) (khz) + #define CCID_DESCRIPTOR_CLOCK_MHZ(mhz) ((mhz) * 1000) + + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the CCID + * device class. + */ + enum CCID_Descriptor_ClassSubclassProtocol_t + { + CCID_CSCP_CCIDClass = 0x0b, /**< Descriptor Class value indicating that the device or interface + * belongs to the CCID class. + */ + CCID_CSCP_NoSpecificSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface + * belongs to no specific subclass of the CCID class. + */ + CCID_CSCP_NoSpecificProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface + * belongs to no specific protocol of the CCID class. + */ + }; + + /** Enum for possible bulk messages between PC and Reader */ + enum CCID_BulkOutMessages_t + { + CCID_PC_to_RDR_IccPowerOn = 0x62, + CCID_PC_to_RDR_IccPowerOff = 0x63, + CCID_PC_to_RDR_GetSlotStatus = 0x65, + CCID_PC_to_RDR_XfrBlock = 0x6f, + CCID_PC_to_RDR_GetParameters = 0x6c, + CCID_PC_to_RDR_ResetParameters = 0x6d, + CCID_PC_to_RDR_SetParameters = 0x61, + CCID_PC_to_RDR_Escape = 0x6b, + CCID_PC_to_RDR_IccClock = 0x6e, + CCID_PC_to_RDR_T0APDU = 0x6a, + CCID_PC_to_RDR_Secure = 0x69, + CCID_PC_to_RDR_Mechanical = 0x71, + CCID_PC_to_RDR_Abort = 0x72, + CCID_PC_to_RDR_SetDataRateAndClockFrequency = 0x73, + + CCID_RDR_to_PC_DataBlock = 0x80, + CCID_RDR_to_PC_SlotStatus = 0x81, + CCID_RDR_to_PC_Parameters = 0x82, + CCID_RDR_to_PC_Escape = 0x83, + CCID_RDR_to_PC_DataRateAndClockFrequency = 0x84, + }; + + /** Enum for the CCID class specific control requests that can be issued by the USB bus host. */ + enum CCID_ClassRequests_t + { + CCID_ABORT = 0x1, + CCID_GET_CLOCK_FREQUENCIES = 0x2, + CCID_GET_DATA_RATES = 0x3, + }; + + /** Enum for the CCID class specific descriptor types. */ + enum CCID_DescriptorTypes_t + { + CCID_DTYPE_Functional = 0x21, /**< CCID class specific Interface functional descriptor. */ + }; + + /* Type Defines: */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + + 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; + } ATTR_PACKED USB_CCID_Descriptor_t; + + typedef struct + { + uint8_t FindexDindex; + uint8_t TCCKST0; + uint8_t GuardTimeT0; + uint8_t WaitingIntegerT0; + uint8_t ClockStop; + } ATTR_PACKED USB_CCID_ProtocolData_T0_t; + + typedef struct + { + uint8_t FindexDindex; + uint8_t TCCKST1; + uint8_t GuardTimeT1; + uint8_t WaitingIntegerT1; + uint8_t ClockStop; + uint8_t FSC; + uint8_t NadValue; + } ATTR_PACKED USB_CCID_ProtocolData_T1_t; + + + /** Enum for a common bulk message header. */ + typedef struct + { + uint8_t MessageType; + uint32_t Length; + uint8_t Slot; + uint8_t Seq; + } ATTR_PACKED USB_CCID_BulkMessage_Header_t; + + typedef struct + { + USB_CCID_BulkMessage_Header_t CCIDHeader; + uint8_t Status; + uint8_t Error; + uint8_t ChainParam; + uint8_t Data[0]; + } ATTR_PACKED USB_CCID_RDR_to_PC_DataBlock_t; + + typedef struct + { + USB_CCID_BulkMessage_Header_t CCIDHeader; + uint8_t Status; + uint8_t Error; + uint8_t ClockStatus; + } ATTR_PACKED USB_CCID_RDR_to_PC_SlotStatus_t; + + typedef struct + { + USB_CCID_BulkMessage_Header_t CCIDHeader; + uint8_t Status; + uint8_t Error; + uint8_t ProtocolNum; + union { + USB_CCID_ProtocolData_T0_t T0; + USB_CCID_ProtocolData_T1_t T1; + } ProtocolData; + } ATTR_PACKED USB_CCID_RDR_to_PC_Parameters_t; + + typedef struct + { + USB_CCID_BulkMessage_Header_t CCIDHeader; + uint8_t Status; + uint8_t Error; + uint8_t RFU; + uint8_t Data[0]; + } ATTR_PACKED USB_CCID_RDR_to_PC_Escape_t; + + typedef struct + { + USB_CCID_BulkMessage_Header_t CCIDHeader; + uint8_t Status; + uint8_t Error; + uint8_t RFU; + uint32_t ClockFrequency; + uint32_t DataRate; + } ATTR_PACKED USB_CCID_RDR_to_PC_DataRateAndClockFrequency_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c new file mode 100644 index 000000000..edc125779 --- /dev/null +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c @@ -0,0 +1,316 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2018. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2018 Filipe Rodrigues (filipepazrodrigues [at] gmail [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_CCID_DRIVER +#define __INCLUDE_FROM_CCID_DEVICE_C +#include "CCIDClassDevice.h" + + +bool CCID_CheckStatusNoError(int status) +{ + return (status & 0xC0) == 0x0; +} + +void CCID_Device_ProcessControlRequest(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) +{ + if (!(Endpoint_IsSETUPReceived())) + return; + + if (USB_ControlRequest.wIndex != CCIDInterfaceInfo->Config.InterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + { + case CCID_ABORT: + { + // Initiates the abort process. + // The host should send 2 messages in the following order: + // - CCID_ABORT control request + // - CCID_PC_t_PCo_RDR_Abort command + // + // If the device is still processing a message, it should fail it until receiving a CCIRPC_to_RDR_Abort + // command. + // + // When the device receives the CCIRPC_to_RDR_Abort message, it replies with RDR_to_PC_SlotStatus + // and the abort process ends. + + // The wValue field contains the slot number (bSlot) in the low byte and the sequence number (bSeq) in + // the high byte + uint8_t Slot = USB_ControlRequest.wValue & 0xFF; + uint8_t Seq = USB_ControlRequest.wValue >> 8; + + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE) && Slot == 0) + { + Endpoint_ClearSETUP(); + + CCIDInterfaceInfo->State.Aborted = true; + CCIDInterfaceInfo->State.AbortedSeq = Seq; + + Endpoint_ClearOUT(); + } + + break; + } + case CCID_GET_CLOCK_FREQUENCIES: + { + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + + Endpoint_ClearSETUP(); + Endpoint_Write_8(0); // Not supported + Endpoint_ClearOUT(); + } + break; + } + case CCID_GET_DATA_RATES: + { + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + + Endpoint_ClearSETUP(); + Endpoint_Write_8(0); // Not supported + Endpoint_ClearOUT(); + } + break; + } + } +} + +bool CCID_Device_ConfigureEndpoints(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) +{ + CCIDInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; + CCIDInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; + + if (!(Endpoint_ConfigureEndpointTable(&CCIDInterfaceInfo->Config.DataINEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&CCIDInterfaceInfo->Config.DataOUTEndpoint, 1))) + return false; + + return true; +} + +void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) +{ + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataOUTEndpoint.Address); + + uint8_t BlockBuffer[0x20]; + CCIDInterfaceInfo->State.Aborted = false; + CCIDInterfaceInfo->State.AbortedSeq = -1; + + if (Endpoint_IsOUTReceived()) + { + USB_CCID_BulkMessage_Header_t CCIDHeader; + CCIDHeader.MessageType = Endpoint_Read_8(); + CCIDHeader.Length = Endpoint_Read_32_LE(); + CCIDHeader.Slot = Endpoint_Read_8(); + CCIDHeader.Seq = Endpoint_Read_8(); + + uint8_t Status; + uint8_t Error = CCID_ERROR_NO_ERROR; + + switch (CCIDHeader.MessageType) + { + case CCID_PC_to_RDR_IccPowerOn: + { + uint8_t AtrLength; + USB_CCID_RDR_to_PC_DataBlock_t* ResponseATR = (USB_CCID_RDR_to_PC_DataBlock_t*)&BlockBuffer; + + ResponseATR->CCIDHeader.MessageType = CCID_RDR_to_PC_DataBlock; + ResponseATR->CCIDHeader.Slot = CCIDHeader.Slot; + ResponseATR->CCIDHeader.Seq = CCIDHeader.Seq; + ResponseATR->ChainParam = 0; + + Status = CALLBACK_CCID_IccPowerOn(ResponseATR->CCIDHeader.Slot, (uint8_t*)ResponseATR->Data, &AtrLength, &Error); + + if (CCID_CheckStatusNoError(Status) && !CCIDInterfaceInfo->State.Aborted) + { + ResponseATR->CCIDHeader.Length = AtrLength; + } + else if (CCIDInterfaceInfo->State.Aborted) + { + Status = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_PRESENTANDACTIVE; + Error = CCID_ERROR_CMD_ABORTED; + AtrLength = 0; + } + else + { + AtrLength = 0; + } + + ResponseATR->Status = Status; + ResponseATR->Error = Error; + + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponseATR, sizeof(USB_CCID_RDR_to_PC_DataBlock_t) + AtrLength, NULL); + Endpoint_ClearIN(); + break; + } + + case CCID_PC_to_RDR_IccPowerOff: + { + USB_CCID_RDR_to_PC_SlotStatus_t* ResponsePowerOff = (USB_CCID_RDR_to_PC_SlotStatus_t*)&BlockBuffer; + ResponsePowerOff->CCIDHeader.MessageType = CCID_RDR_to_PC_SlotStatus; + ResponsePowerOff->CCIDHeader.Length = 0; + ResponsePowerOff->CCIDHeader.Slot = CCIDHeader.Slot; + ResponsePowerOff->CCIDHeader.Seq = CCIDHeader.Seq; + + ResponsePowerOff->ClockStatus = 0; + + Status = CALLBACK_CCID_IccPowerOff(CCIDHeader.Slot, &Error); + + ResponsePowerOff->Status = Status; + ResponsePowerOff->Error = Error; + + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponsePowerOff, sizeof(USB_CCID_RDR_to_PC_SlotStatus_t), NULL); + Endpoint_ClearIN(); + break; + } + + case CCID_PC_to_RDR_GetSlotStatus: + { + USB_CCID_RDR_to_PC_SlotStatus_t* ResponseSlotStatus = (USB_CCID_RDR_to_PC_SlotStatus_t*)&BlockBuffer; + ResponseSlotStatus->CCIDHeader.MessageType = CCID_RDR_to_PC_SlotStatus; + ResponseSlotStatus->CCIDHeader.Length = 0; + ResponseSlotStatus->CCIDHeader.Slot = CCIDHeader.Slot; + ResponseSlotStatus->CCIDHeader.Seq = CCIDHeader.Seq; + + ResponseSlotStatus->ClockStatus = 0; + + Status = CALLBACK_CCID_GetSlotStatus(CCIDHeader.Slot, &Error); + + ResponseSlotStatus->Status = Status; + ResponseSlotStatus->Error = Error; + + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponseSlotStatus, sizeof(USB_CCID_RDR_to_PC_SlotStatus_t), NULL); + Endpoint_ClearIN(); + break; + } + + case CCID_PC_to_RDR_XfrBlock: + { + uint8_t Bwi = Endpoint_Read_8(); + uint16_t LevelParameter = Endpoint_Read_16_LE(); + uint8_t ReceivedBuffer[0x4]; + + (void)Bwi; + (void)LevelParameter; + + Endpoint_Read_Stream_LE(ReceivedBuffer, sizeof(ReceivedBuffer), NULL); + + uint8_t SendBuffer[0x2] = {0x90, 0x00}; + uint8_t SendLength = sizeof(SendBuffer); + + USB_CCID_RDR_to_PC_DataBlock_t* ResponseBlock = (USB_CCID_RDR_to_PC_DataBlock_t*)&BlockBuffer; + ResponseBlock->CCIDHeader.MessageType = CCID_RDR_to_PC_DataBlock; + ResponseBlock->CCIDHeader.Slot = CCIDHeader.Slot; + ResponseBlock->CCIDHeader.Seq = CCIDHeader.Seq; + + ResponseBlock->ChainParam = 0; + + //TODO: Callback + Status = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE; + + if (CCID_CheckStatusNoError(Status) && !CCIDInterfaceInfo->State.Aborted) + { + ResponseBlock->CCIDHeader.Length = SendLength; + memcpy(&ResponseBlock->Data, SendBuffer, SendLength); + } + else if(CCIDInterfaceInfo->State.Aborted) + { + Status = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_PRESENTANDACTIVE; + Error = CCID_ERROR_CMD_ABORTED; + SendLength = 0; + } + else + { + SendLength = 0; + } + + ResponseBlock->Status = Status; + ResponseBlock->Error = Error; + + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponseBlock, sizeof(USB_CCID_RDR_to_PC_DataBlock_t) + SendLength, NULL); + Endpoint_ClearIN(); + break; + } + + case CCID_PC_to_RDR_Abort: + { + USB_CCID_RDR_to_PC_SlotStatus_t* ResponseAbort = (USB_CCID_RDR_to_PC_SlotStatus_t*)&BlockBuffer; + ResponseAbort->CCIDHeader.MessageType = CCID_RDR_to_PC_SlotStatus; + ResponseAbort->CCIDHeader.Length = 0; + ResponseAbort->CCIDHeader.Slot = CCIDHeader.Slot; + ResponseAbort->CCIDHeader.Seq = CCIDHeader.Seq; + + ResponseAbort->ClockStatus = 0; + + Status = CALLBACK_CCID_Abort(CCIDHeader.Slot, CCIDHeader.Seq, &Error); + + ResponseAbort->Status = Status; + ResponseAbort->Error = Error; + + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponseAbort, sizeof(USB_CCID_RDR_to_PC_SlotStatus_t), NULL); + Endpoint_ClearIN(); + break; + } + default: + { + memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); + Endpoint_ClearIN(); + } + } + } +} + +#endif diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h new file mode 100644 index 000000000..29a79f02d --- /dev/null +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h @@ -0,0 +1,127 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2018. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2018 Filipe Rodrigues (filipepazrodrigues [at] gmail [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Device mode driver for the library USB CCID Class driver. + * + * Device mode driver for the library USB CCID Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassCCID + * \defgroup Group_USBClassCCIDDevice CCID Class Device Mode Driver + * + * \section Sec_USBClassCCIDDevice_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_USBClassCCIDDevice_ModDescription Module Description + * Device Mode USB Class driver framework interface, for the CCID USB Class driver. + * + * @{ + */ + +#ifndef _CCID_CLASS_DEVICE_H_ +#define _CCID_CLASS_DEVICE_H_ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/CCIDClassCommon.h" + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief CCID Class Device Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made for each CCID interface + * within the user application, and passed to each of the CCID class driver functions as the + * CCIDInterfaceInfo parameter. This stores each CCID interface's configuration and state information. + */ + typedef struct + { + struct + { + uint8_t InterfaceNumber; /**< Interface number of the CCID interface within the device. */ + uint8_t TotalSlots; /**< Total of slots no this device. */ + USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ + USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool Aborted; //< Set if host has started an abort process + uint8_t AbortedSeq; //< Sequence number for the current abort process + } State; /**< State data for the USB class interface within the device. All elements in this section + * are reset to their defaults when the interface is enumerated. + */ + } USB_ClassInfo_CCID_Device_t; + + /* Function Prototypes: */ + /** Configures the endpoints of a given CCID interface, ready for use. This should be linked to the library + * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing + * the given CCID interface is selected. + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration. + * + * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. + */ + bool CCID_Device_ConfigureEndpoints(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Processes incoming control requests from the host, that are directed to the given CCID class interface. This should be + * linked to the library \ref EVENT_USB_Device_ControlRequest() event. + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. + */ + void CCID_Device_ProcessControlRequest(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** General management task for a given CCID class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. + */ + void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + uint8_t CALLBACK_CCID_IccPowerOn(uint8_t slot, uint8_t* atr, uint8_t* atrSize, uint8_t* error); + + uint8_t CALLBACK_CCID_IccPowerOff(uint8_t slot, uint8_t* error); + + uint8_t CALLBACK_CCID_GetSlotStatus(uint8_t slot, uint8_t* error); + + uint8_t CALLBACK_CCID_XfrBlock(uint8_t slot, uint8_t* error, uint8_t* receivedBuffer, uint8_t receivedBufferSize, uint8_t* sendBuffer, uint8_t* sentBufferSize); + + uint8_t CALLBACK_CCID_Abort(uint8_t slot, uint8_t seq, uint8_t* error); + + +#endif + +/** @} */ diff --git a/LUFA/Drivers/USB/USB.h b/LUFA/Drivers/USB/USB.h index afb823e13..1a3b283f3 100644 --- a/LUFA/Drivers/USB/USB.h +++ b/LUFA/Drivers/USB/USB.h @@ -410,6 +410,7 @@ #include "Class/AndroidAccessoryClass.h" #include "Class/AudioClass.h" + #include "Class/CCIDClass.h" #include "Class/CDCClass.h" #include "Class/HIDClass.h" #include "Class/MassStorageClass.h" -- cgit v1.2.3 From be13902026cdfea208a3d3016657c259361a0aaf Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Sun, 17 Jun 2018 15:50:25 -0700 Subject: Review fixes - Added documentation - Removed incomplete XfrBlock message - Renamed Attr to Atr --- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c | 51 ------------------------- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h | 39 ++++++++++++++++++- 2 files changed, 37 insertions(+), 53 deletions(-) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c index edc125779..11c20f0b3 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c @@ -228,57 +228,6 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) break; } - case CCID_PC_to_RDR_XfrBlock: - { - uint8_t Bwi = Endpoint_Read_8(); - uint16_t LevelParameter = Endpoint_Read_16_LE(); - uint8_t ReceivedBuffer[0x4]; - - (void)Bwi; - (void)LevelParameter; - - Endpoint_Read_Stream_LE(ReceivedBuffer, sizeof(ReceivedBuffer), NULL); - - uint8_t SendBuffer[0x2] = {0x90, 0x00}; - uint8_t SendLength = sizeof(SendBuffer); - - USB_CCID_RDR_to_PC_DataBlock_t* ResponseBlock = (USB_CCID_RDR_to_PC_DataBlock_t*)&BlockBuffer; - ResponseBlock->CCIDHeader.MessageType = CCID_RDR_to_PC_DataBlock; - ResponseBlock->CCIDHeader.Slot = CCIDHeader.Slot; - ResponseBlock->CCIDHeader.Seq = CCIDHeader.Seq; - - ResponseBlock->ChainParam = 0; - - //TODO: Callback - Status = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE; - - if (CCID_CheckStatusNoError(Status) && !CCIDInterfaceInfo->State.Aborted) - { - ResponseBlock->CCIDHeader.Length = SendLength; - memcpy(&ResponseBlock->Data, SendBuffer, SendLength); - } - else if(CCIDInterfaceInfo->State.Aborted) - { - Status = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_PRESENTANDACTIVE; - Error = CCID_ERROR_CMD_ABORTED; - SendLength = 0; - } - else - { - SendLength = 0; - } - - ResponseBlock->Status = Status; - ResponseBlock->Error = Error; - - Endpoint_ClearOUT(); - - Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); - Endpoint_Write_Stream_LE(ResponseBlock, sizeof(USB_CCID_RDR_to_PC_DataBlock_t) + SendLength, NULL); - Endpoint_ClearIN(); - break; - } - case CCID_PC_to_RDR_Abort: { USB_CCID_RDR_to_PC_SlotStatus_t* ResponseAbort = (USB_CCID_RDR_to_PC_SlotStatus_t*)&BlockBuffer; diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h index 29a79f02d..5acc33af5 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h @@ -111,14 +111,49 @@ */ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + /** CCID class driver callback for PC_TO_RDR_IccPowerOn CCID message + * When the ICC is inserted into a slot of a CCID, the CCID can activate the ICC, and the ICC will respond with an ATR + * (answer to reset) + * + * \param[in] slot The slot currently being powered on + * \param[in, out] atr Pointer to an array where the ATR being sent to the device when the Icc is powered on is. + * \param[out] atrSize The size of the ATR being sent. Maximum size is 15 + * \param[out] error The result of the operation, or error + * + * \return uint8_t The command result + */ uint8_t CALLBACK_CCID_IccPowerOn(uint8_t slot, uint8_t* atr, uint8_t* atrSize, uint8_t* error); + /** CCID class driver callback for PC_TO_RDR_IccPowerOff CCID message + * Turns off the ICC + * + * \param[in] slot The slot currently being powered off + * \param[out] error The result of the operation, or error + * + * \return uint8_t The command result + */ uint8_t CALLBACK_CCID_IccPowerOff(uint8_t slot, uint8_t* error); + /** CCID class driver callback for PC_TO_RDR_GetSlotStatus CCID message + * Retrieves the current status of a given slot + * + * \param[in] slot The slot from which we want to retrieve the status + * \param[out] error The result of the operation, or error + * + * \return uint8_t The command result + */ uint8_t CALLBACK_CCID_GetSlotStatus(uint8_t slot, uint8_t* error); - uint8_t CALLBACK_CCID_XfrBlock(uint8_t slot, uint8_t* error, uint8_t* receivedBuffer, uint8_t receivedBufferSize, uint8_t* sendBuffer, uint8_t* sentBufferSize); - + /** CCID class driver callback for CCID_PC_to_RDR_Abort CCID message + * Aborts a BULK out message previously sent to a slot + * + * \param[in] slot The slot to where the message being aborted was sent to + * \param[in] seq The current sequence number for this message. Must be checked against to the current + * abort massage being sent at the control pipe + * \param[out] error The result of the operation, or error + * + * \return uint8_t The command result + */ uint8_t CALLBACK_CCID_Abort(uint8_t slot, uint8_t seq, uint8_t* error); -- cgit v1.2.3 From bc57f4ea5afd29f2e0f0175d14cf1540b4408de8 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Sun, 24 Jun 2018 16:41:58 +1000 Subject: Reformatting and add const qualifiers. --- LUFA/Drivers/USB/Class/CCIDClass.h | 9 ++-- LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h | 3 +- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c | 13 +++-- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h | 67 +++++++++++++++---------- 4 files changed, 55 insertions(+), 37 deletions(-) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/Class/CCIDClass.h b/LUFA/Drivers/USB/Class/CCIDClass.h index 681326f65..2e61571bc 100644 --- a/LUFA/Drivers/USB/Class/CCIDClass.h +++ b/LUFA/Drivers/USB/Class/CCIDClass.h @@ -45,15 +45,14 @@ * \section Sec_USBClassCCID_Dependencies Module Source Dependencies * The following files must be built with any user project that uses this module: * - LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) - * - LUFA/Drivers/USB/Class/Host/CCIDClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) * * \section Sec_USBClassCCID_ModDescription Module Description - * CCID Class Driver module. This module contains an internal implementation of the USB CCID Class, for both Device - * and Host USB modes. User applications can use this class driver instead of implementing the CCID class manually - * via the low-level LUFA APIs. + * CCID Class Driver module. This module contains an internal implementation of the USB CCID Class, for Device USB + * mode. User applications can use this class driver instead of implementing the CCID class manually via the low-level + * LUFA APIs. * * This module is designed to simplify the user code by exposing only the required interface needed to interface with - * Hosts or Devices using the USB CCID Class. + * Devices using the USB CCID Class. * * \warning * LUFA is not a secure USB stack, and has not undergone, not is it expected to pass, any form of security audit. The diff --git a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h index 61239ec8a..6cedcad36 100644 --- a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h +++ b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h @@ -233,7 +233,8 @@ uint8_t Status; uint8_t Error; uint8_t ProtocolNum; - union { + union + { USB_CCID_ProtocolData_T0_t T0; USB_CCID_ProtocolData_T1_t T1; } ProtocolData; diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c index 11c20f0b3..0595e0715 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c @@ -39,7 +39,7 @@ #include "CCIDClassDevice.h" -bool CCID_CheckStatusNoError(int status) +bool CCID_CheckStatusNoError(uint8_t status) { return (status & 0xC0) == 0x0; } @@ -84,6 +84,7 @@ void CCID_Device_ProcessControlRequest(USB_ClassInfo_CCID_Device_t* const CCIDIn break; } + case CCID_GET_CLOCK_FREQUENCIES: { if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) @@ -95,6 +96,7 @@ void CCID_Device_ProcessControlRequest(USB_ClassInfo_CCID_Device_t* const CCIDIn } break; } + case CCID_GET_DATA_RATES: { if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) @@ -154,7 +156,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ResponseATR->CCIDHeader.Seq = CCIDHeader.Seq; ResponseATR->ChainParam = 0; - Status = CALLBACK_CCID_IccPowerOn(ResponseATR->CCIDHeader.Slot, (uint8_t*)ResponseATR->Data, &AtrLength, &Error); + Status = CALLBACK_CCID_IccPowerOn(CCIDInterfaceInfo, ResponseATR->CCIDHeader.Slot, (uint8_t*)ResponseATR->Data, &AtrLength, &Error); if (CCID_CheckStatusNoError(Status) && !CCIDInterfaceInfo->State.Aborted) { @@ -192,7 +194,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ResponsePowerOff->ClockStatus = 0; - Status = CALLBACK_CCID_IccPowerOff(CCIDHeader.Slot, &Error); + Status = CALLBACK_CCID_IccPowerOff(CCIDInterfaceInfo, CCIDHeader.Slot, &Error); ResponsePowerOff->Status = Status; ResponsePowerOff->Error = Error; @@ -215,7 +217,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ResponseSlotStatus->ClockStatus = 0; - Status = CALLBACK_CCID_GetSlotStatus(CCIDHeader.Slot, &Error); + Status = CALLBACK_CCID_GetSlotStatus(CCIDInterfaceInfo, CCIDHeader.Slot, &Error); ResponseSlotStatus->Status = Status; ResponseSlotStatus->Error = Error; @@ -238,7 +240,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ResponseAbort->ClockStatus = 0; - Status = CALLBACK_CCID_Abort(CCIDHeader.Slot, CCIDHeader.Seq, &Error); + Status = CALLBACK_CCID_Abort(CCIDInterfaceInfo, CCIDHeader.Slot, CCIDHeader.Seq, &Error); ResponseAbort->Status = Status; ResponseAbort->Error = Error; @@ -250,6 +252,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_ClearIN(); break; } + default: { memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h index 5acc33af5..245e12665 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h @@ -115,46 +115,61 @@ * When the ICC is inserted into a slot of a CCID, the CCID can activate the ICC, and the ICC will respond with an ATR * (answer to reset) * - * \param[in] slot The slot currently being powered on - * \param[in, out] atr Pointer to an array where the ATR being sent to the device when the Icc is powered on is. - * \param[out] atrSize The size of the ATR being sent. Maximum size is 15 - * \param[out] error The result of the operation, or error + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. + * \param[in] slot The slot ID currently being powered on. + * \param[in,out] atr Pointer to an array containing the Power On ATR being sent to the device. + * \param[out] atrSize The size of the ATR being sent (up to 15 bytes maximum). + * \param[out] error The result of the operation, or error. * - * \return uint8_t The command result + * \return The command result code. */ - uint8_t CALLBACK_CCID_IccPowerOn(uint8_t slot, uint8_t* atr, uint8_t* atrSize, uint8_t* error); + uint8_t CALLBACK_CCID_IccPowerOn(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, + uint8_t slot, + uint8_t* const atr, + uint8_t* const atrSize, + uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_IccPowerOff CCID message * Turns off the ICC - * - * \param[in] slot The slot currently being powered off - * \param[out] error The result of the operation, or error - * - * \return uint8_t The command result + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. + * \param[in] slot The slot ID currently being powered off. + * \param[out] error The result of the operation, or error. + * + * \return The command result code. */ - uint8_t CALLBACK_CCID_IccPowerOff(uint8_t slot, uint8_t* error); + uint8_t CALLBACK_CCID_IccPowerOff(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, + uint8_t slot, + uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_GetSlotStatus CCID message * Retrieves the current status of a given slot - * - * \param[in] slot The slot from which we want to retrieve the status - * \param[out] error The result of the operation, or error - * - * \return uint8_t The command result + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. + * \param[in] slot The slot ID from which we want to retrieve the status. + * \param[out] error The result of the operation, or error. + * + * \return The command result code. */ - uint8_t CALLBACK_CCID_GetSlotStatus(uint8_t slot, uint8_t* error); + uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, + uint8_t slot, + uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for CCID_PC_to_RDR_Abort CCID message * Aborts a BULK out message previously sent to a slot - * - * \param[in] slot The slot to where the message being aborted was sent to - * \param[in] seq The current sequence number for this message. Must be checked against to the current - * abort massage being sent at the control pipe - * \param[out] error The result of the operation, or error - * - * \return uint8_t The command result + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. + * \param[in] slot The slot ID to where the message being aborted was sent to. + * \param[in] seq The current sequence number for this message. Must be checked against + * the current abort message being sent at the control pipe. + * \param[out] error The result of the operation, or error. + * + * \return The command result code. */ - uint8_t CALLBACK_CCID_Abort(uint8_t slot, uint8_t seq, uint8_t* error); + uint8_t CALLBACK_CCID_Abort(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, + uint8_t slot, + uint8_t seq, + uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); #endif -- cgit v1.2.3 From 1e9e7bc8b88af32f466f7438a06fb8dc96b3035d Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Sun, 17 Jun 2018 17:51:09 -0700 Subject: CCID: Add support for PC-to-Reader XfrBlock message --- LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h | 20 ++++++++ LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c | 64 ++++++++++++++++++++++--- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h | 22 +++++++++ 3 files changed, 99 insertions(+), 7 deletions(-) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h index 6cedcad36..cf8fdbae0 100644 --- a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h +++ b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h @@ -153,6 +153,26 @@ CCID_DTYPE_Functional = 0x21, /**< CCID class specific Interface functional descriptor. */ }; + enum CCID_Features_Auto_t + { + CCID_Features_Auto_None = 0x0, + CCID_Features_Auto_ParameterConfiguration = 0x2, + CCID_Features_Auto_ICCActivation = 0x4, + CCID_Features_Auto_VoltageSelection = 0x8, + + CCID_Features_Auto_ICCClockFrequencyChange = 0x10, + CCID_Features_Auto_ICCBaudRateChange = 0x20, + CCID_Features_Auto_ParameterNegotiation = 0x40, + CCID_Features_Auto_PPS = 0x80, + }; + + enum CCID_Features_ExchangeLevel_t + { + CCID_Features_ExchangeLevel_TPDU = 0x00010000, + CCID_Features_ExchangeLevel_ShortAPDU = 0x00020000, + CCID_Features_ExchangeLevel_ShortExtendedAPDU = 0x00040000 + }; + /* Type Defines: */ typedef struct { diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c index 0595e0715..450ed9d9c 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c @@ -129,7 +129,9 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) { Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataOUTEndpoint.Address); - uint8_t BlockBuffer[0x20]; + uint8_t RequestBuffer[0x40 - sizeof(USB_CCID_BulkMessage_Header_t)]; + uint8_t ResponseBuffer[0x40]; + CCIDInterfaceInfo->State.Aborted = false; CCIDInterfaceInfo->State.AbortedSeq = -1; @@ -149,7 +151,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) case CCID_PC_to_RDR_IccPowerOn: { uint8_t AtrLength; - USB_CCID_RDR_to_PC_DataBlock_t* ResponseATR = (USB_CCID_RDR_to_PC_DataBlock_t*)&BlockBuffer; + USB_CCID_RDR_to_PC_DataBlock_t* ResponseATR = (USB_CCID_RDR_to_PC_DataBlock_t*)&ResponseBuffer; ResponseATR->CCIDHeader.MessageType = CCID_RDR_to_PC_DataBlock; ResponseATR->CCIDHeader.Slot = CCIDHeader.Slot; @@ -186,7 +188,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) case CCID_PC_to_RDR_IccPowerOff: { - USB_CCID_RDR_to_PC_SlotStatus_t* ResponsePowerOff = (USB_CCID_RDR_to_PC_SlotStatus_t*)&BlockBuffer; + USB_CCID_RDR_to_PC_SlotStatus_t* ResponsePowerOff = (USB_CCID_RDR_to_PC_SlotStatus_t*)&ResponseBuffer; ResponsePowerOff->CCIDHeader.MessageType = CCID_RDR_to_PC_SlotStatus; ResponsePowerOff->CCIDHeader.Length = 0; ResponsePowerOff->CCIDHeader.Slot = CCIDHeader.Slot; @@ -209,7 +211,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) case CCID_PC_to_RDR_GetSlotStatus: { - USB_CCID_RDR_to_PC_SlotStatus_t* ResponseSlotStatus = (USB_CCID_RDR_to_PC_SlotStatus_t*)&BlockBuffer; + USB_CCID_RDR_to_PC_SlotStatus_t* ResponseSlotStatus = (USB_CCID_RDR_to_PC_SlotStatus_t*)&ResponseBuffer; ResponseSlotStatus->CCIDHeader.MessageType = CCID_RDR_to_PC_SlotStatus; ResponseSlotStatus->CCIDHeader.Length = 0; ResponseSlotStatus->CCIDHeader.Slot = CCIDHeader.Slot; @@ -230,9 +232,57 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) break; } + case CCID_PC_to_RDR_XfrBlock: + { + uint8_t Bwi = Endpoint_Read_8(); + uint16_t LevelParameter = Endpoint_Read_16_LE(); + uint8_t ReceivedBuffer[0x4]; + + (void)Bwi; + (void)LevelParameter; + + Endpoint_Read_Stream_LE(ReceivedBuffer, sizeof(ReceivedBuffer), NULL); + + uint8_t ResponseDataLength = 0; + + USB_CCID_RDR_to_PC_DataBlock_t* ResponseBlock = (USB_CCID_RDR_to_PC_DataBlock_t*)&ResponseBuffer; + ResponseBlock->CCIDHeader.MessageType = CCID_RDR_to_PC_DataBlock; + ResponseBlock->CCIDHeader.Slot = CCIDHeader.Slot; + ResponseBlock->CCIDHeader.Seq = CCIDHeader.Seq; + + ResponseBlock->ChainParam = 0; + + Status = CALLBACK_CCID_XfrBlock(CCIDInterfaceInfo, CCIDHeader.Slot, RequestBuffer, CCIDHeader.Length, (uint8_t*) &ResponseBlock->Data, &ResponseDataLength, &Error); + + if (CCID_CheckStatusNoError(Status) && !CCIDInterfaceInfo->State.Aborted) + { + ResponseBlock->CCIDHeader.Length = ResponseDataLength; + } + else if(CCIDInterfaceInfo->State.Aborted) + { + Status = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_PRESENTANDACTIVE; + Error = CCID_ERROR_CMD_ABORTED; + ResponseDataLength = 0; + } + else + { + ResponseDataLength = 0; + } + + ResponseBlock->Status = Status; + ResponseBlock->Error = Error; + + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponseBlock, sizeof(USB_CCID_RDR_to_PC_DataBlock_t) + ResponseDataLength, NULL); + Endpoint_ClearIN(); + break; + } + case CCID_PC_to_RDR_Abort: { - USB_CCID_RDR_to_PC_SlotStatus_t* ResponseAbort = (USB_CCID_RDR_to_PC_SlotStatus_t*)&BlockBuffer; + USB_CCID_RDR_to_PC_SlotStatus_t* ResponseAbort = (USB_CCID_RDR_to_PC_SlotStatus_t*)&ResponseBuffer; ResponseAbort->CCIDHeader.MessageType = CCID_RDR_to_PC_SlotStatus; ResponseAbort->CCIDHeader.Length = 0; ResponseAbort->CCIDHeader.Slot = CCIDHeader.Slot; @@ -255,10 +305,10 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) default: { - memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); + memset(ResponseBuffer, 0x00, sizeof(ResponseBuffer)); Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); - Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); + Endpoint_Write_Stream_LE(ResponseBuffer, sizeof(ResponseBuffer), NULL); Endpoint_ClearIN(); } } diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h index 245e12665..d101723c3 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h @@ -155,6 +155,28 @@ uint8_t slot, uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); + /** CCID class driver callback for PC_TO_RDR_XfrBlock CCID message + * Send a block of bytes from the host to a slot in the device + * and also received a block of bytes as a response + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. + * \param[in] slot The slot ID from which we want to retrieve the status. + * \param[in] receivedBuffer Pointer to an array holding the received block of bytes + * \param[in] receivedBufferSize The size of the received block of bytes + * \param[out] sendBuffer Pointer to a buffer which will hold the bytes being sent back to the host + * \param[out] sentBufferSize The size of the block of bytes being sent back to the host + * \param[out] error The result of the operation, or error. + * + * \return The command result code. + */ + uint8_t CALLBACK_CCID_XfrBlock(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, + uint8_t slot, + uint8_t* const receivedBuffer, + uint8_t receivedBufferSize, + uint8_t* const sendBuffer, + uint8_t* const sentBufferSize, + uint8_t* const error); + /** CCID class driver callback for CCID_PC_to_RDR_Abort CCID message * Aborts a BULK out message previously sent to a slot * -- cgit v1.2.3 From a877ffb6265ea3a18f1c95f61fdddc8b57c518cc Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Sun, 8 Jul 2018 20:18:27 -0700 Subject: CCID: Initial support for GetParameters and SetParameters --- LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h | 3 ++ LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c | 69 +++++++++++++++++++++++++ LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h | 33 ++++++++++++ 3 files changed, 105 insertions(+) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h index cf8fdbae0..da92381f6 100644 --- a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h +++ b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h @@ -81,6 +81,7 @@ #define CCID_ICCSTATUS_NOICCPRESENT (1 << 1) #define CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR 0 + #define CCID_COMMANDSTATUS_ERROR 1 #define CCID_COMMANDSTATUS_FAILED (1 << 6) #define CCID_COMMANDSTATUS_TIMEEXTENSIONREQUESTED (2 << 6) #define CCID_COMMANDSTATUS_RFU (3 << 6) @@ -91,6 +92,8 @@ #define CCID_ERROR_CMD_ABORTED 0xFF #define CCID_ERROR_CMD_NOT_ABORTED 0xFF + #define CCID_ERROR_PARAMETERS_PROTOCOL_NOT_SUPPORTED 0x7 + #define CCID_ERROR_SLOT_NOT_FOUND 5 #define CCID_DESCRIPTOR_CLOCK_KHZ(khz) (khz) diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c index 450ed9d9c..34f03c2c1 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c @@ -231,7 +231,76 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_ClearIN(); break; } + case CCID_PC_to_RDR_SetParameters: + { + uint8_t ProtocolNum = Endpoint_Read_8(); + uint8_t RFU = Endpoint_Read_16_LE(); + + (void)RFU; + + USB_CCID_RDR_to_PC_Parameters_t* ResponseParametersStatus = (USB_CCID_RDR_to_PC_Parameters_t*)&ResponseBuffer; + ResponseParametersStatus->CCIDHeader.MessageType = CCID_RDR_to_PC_Parameters; + ResponseParametersStatus->CCIDHeader.Length = 0; + ResponseParametersStatus->CCIDHeader.Slot = CCIDHeader.Slot; + ResponseParametersStatus->CCIDHeader.Seq = CCIDHeader.Seq; + + if(ProtocolNum == CCID_PROTOCOLNUM_T0) + { + if(CCIDHeader.Length * sizeof(uint8_t) == sizeof(USB_CCID_ProtocolData_T0_t)) + { + + Endpoint_Read_Stream_LE(RequestBuffer, CCIDHeader.Length * sizeof(uint8_t), NULL); + Status = CALLBACK_CCID_SetParameters_T0(CCIDInterfaceInfo, CCIDHeader.Slot, &Error, (USB_CCID_ProtocolData_T0_t*) RequestBuffer); + if(CCID_CheckStatusNoError(Status)) + { + ResponseParametersStatus->CCIDHeader.Length = CCIDHeader.Length; + Status = CALLBACK_CCID_GetParameters_T0(CCIDInterfaceInfo, CCIDHeader.Slot, &Error, &ResponseParametersStatus->ProtocolNum, (USB_CCID_ProtocolData_T0_t*) &ResponseParametersStatus->ProtocolData); + } + } + else + { + //unexpected length + Status = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_PRESENTANDACTIVE; + } + } + else + { + ResponseParametersStatus->ProtocolNum = CCID_PROTOCOLNUM_T0; + //for now, we don't support T=1 protocol + Error = CCID_ERROR_PARAMETERS_PROTOCOL_NOT_SUPPORTED; + Status = CCID_COMMANDSTATUS_ERROR | CCID_ICCSTATUS_PRESENTANDACTIVE; + } + + ResponseParametersStatus->Status = Status; + ResponseParametersStatus->Error = Error; + + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponseParametersStatus, sizeof(USB_CCID_BulkMessage_Header_t) + 3 + ResponseParametersStatus->CCIDHeader.Length , NULL); + Endpoint_ClearIN(); + break; + } + case CCID_PC_to_RDR_GetParameters: + { + USB_CCID_RDR_to_PC_Parameters_t* ResponseParametersStatus = (USB_CCID_RDR_to_PC_Parameters_t*)&ResponseBuffer; + ResponseParametersStatus->CCIDHeader.MessageType = CCID_RDR_to_PC_Parameters; + ResponseParametersStatus->CCIDHeader.Length = sizeof(USB_CCID_ProtocolData_T0_t); + ResponseParametersStatus->CCIDHeader.Slot = CCIDHeader.Slot; + ResponseParametersStatus->CCIDHeader.Seq = CCIDHeader.Seq; + + Status = CALLBACK_CCID_GetParameters_T0(CCIDInterfaceInfo, CCIDHeader.Slot, &Error, &ResponseParametersStatus->ProtocolNum, (USB_CCID_ProtocolData_T0_t*) &ResponseParametersStatus->ProtocolData); + + ResponseParametersStatus->Status = Status; + ResponseParametersStatus->Error = Error; + Endpoint_ClearOUT(); + + Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_Write_Stream_LE(ResponseParametersStatus, sizeof(USB_CCID_BulkMessage_Header_t) + 3 + ResponseParametersStatus->CCIDHeader.Length , NULL); + Endpoint_ClearIN(); + break; + } case CCID_PC_to_RDR_XfrBlock: { uint8_t Bwi = Endpoint_Read_8(); diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h index d101723c3..e6b774fda 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h @@ -84,6 +84,7 @@ } State; /**< State data for the USB class interface within the device. All elements in this section * are reset to their defaults when the interface is enumerated. */ + USB_CCID_ProtocolData_T0_t ProtocolData; } USB_ClassInfo_CCID_Device_t; /* Function Prototypes: */ @@ -155,6 +156,38 @@ uint8_t slot, uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); + + /** CCID class driver callback for PC_TO_RDR_SetParameters CCID message for T=0 + * Sets the current parameters of a given slot + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration, state and protocol data. + * \param[in] slot The slot ID from which we want to retrieve the status. + * \param[out] error The result of the operation, or error. + * \param[out] t0 Pointer to a buffer containing the new parameters + * + * \return The command result code. + */ + uint8_t CALLBACK_CCID_SetParameters_T0(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, + uint8_t slot, + uint8_t* const error, + USB_CCID_ProtocolData_T0_t* const t0); + + /** CCID class driver callback for PC_TO_RDR_SetParameters CCID message for T=0 + * Retrieves the current parameters of a given slot + * + * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration, state and protocol data. + * \param[in] slot The slot ID from which we want to retrieve the status. + * \param[out] error The result of the operation, or error. + * \param[out] t0 Pointer to a buffer where the parameters will be returned + * + * \return The command result code. + */ + uint8_t CALLBACK_CCID_GetParameters_T0(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, + uint8_t slot, + uint8_t* const error, + uint8_t* const ProtocolNum, + USB_CCID_ProtocolData_T0_t* const t0); + /** CCID class driver callback for PC_TO_RDR_XfrBlock CCID message * Send a block of bytes from the host to a slot in the device * and also received a block of bytes as a response -- cgit v1.2.3 From 2a057a7209a1a4457306a2bb42894f42a05fffcd Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 6 Aug 2018 19:43:44 +1000 Subject: Clean up CCID class driver and associated demos. --- LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h | 50 +++++++------- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c | 31 +++++---- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h | 92 ++++++++++++------------- 3 files changed, 89 insertions(+), 84 deletions(-) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h index da92381f6..ce7d0b370 100644 --- a/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h +++ b/LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h @@ -65,39 +65,39 @@ #endif /* Macros: */ - #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_CURRENT_SPEC_RELEASE_NUMBER 0x0110 + #define CCID_VOLTAGESUPPORT_5V 0 + #define CCID_VOLTAGESUPPORT_3V (1 << 0) + #define CCID_VOLTAGESUPPORT_1V8 (1 << 1) - #define CCID_PROTOCOLS_T0 (1 << 0) - #define CCID_PROTOCOLS_T1 (1 << 1) + #define CCID_PROTOCOLS_T0 (1 << 0) + #define CCID_PROTOCOLS_T1 (1 << 1) - #define CCID_PROTOCOLNUM_T0 0 - #define CCID_PROTOCOLNUM_T1 (1 << 0) + #define CCID_PROTOCOLNUM_T0 0 + #define CCID_PROTOCOLNUM_T1 (1 << 0) - #define CCID_ICCSTATUS_PRESENTANDACTIVE 0 - #define CCID_ICCSTATUS_PRESENTANDINACTIVE (1 << 0) - #define CCID_ICCSTATUS_NOICCPRESENT (1 << 1) + #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_ERROR 1 - #define CCID_COMMANDSTATUS_FAILED (1 << 6) - #define CCID_COMMANDSTATUS_TIMEEXTENSIONREQUESTED (2 << 6) - #define CCID_COMMANDSTATUS_RFU (3 << 6) + #define CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR 0 + #define CCID_COMMANDSTATUS_ERROR 1 + #define CCID_COMMANDSTATUS_FAILED (1 << 6) + #define CCID_COMMANDSTATUS_TIMEEXTENSIONREQUESTED (2 << 6) + #define CCID_COMMANDSTATUS_RFU (3 << 6) - #define CCID_ERROR_RFU_START 0x80 - #define CCID_ERROR_NO_ERROR 0x80 - #define CCID_ERROR_NOT_SUPPORTED 0 - #define CCID_ERROR_CMD_ABORTED 0xFF - #define CCID_ERROR_CMD_NOT_ABORTED 0xFF + #define CCID_ERROR_RFU_START 0x80 + #define CCID_ERROR_NO_ERROR 0x80 + #define CCID_ERROR_NOT_SUPPORTED 0 + #define CCID_ERROR_CMD_ABORTED 0xFF + #define CCID_ERROR_CMD_NOT_ABORTED 0xFF - #define CCID_ERROR_PARAMETERS_PROTOCOL_NOT_SUPPORTED 0x7 + #define CCID_ERROR_PARAMETERS_PROTOCOL_NOT_SUPPORTED 0x7 - #define CCID_ERROR_SLOT_NOT_FOUND 5 + #define CCID_ERROR_SLOT_NOT_FOUND 5 - #define CCID_DESCRIPTOR_CLOCK_KHZ(khz) (khz) - #define CCID_DESCRIPTOR_CLOCK_MHZ(mhz) ((mhz) * 1000) + #define CCID_DESCRIPTOR_CLOCK_KHZ(khz) (khz) + #define CCID_DESCRIPTOR_CLOCK_MHZ(mhz) ((mhz) * 1000) /* Enums: */ diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c index 34f03c2c1..5bc4c934b 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c @@ -39,9 +39,9 @@ #include "CCIDClassDevice.h" -bool CCID_CheckStatusNoError(uint8_t status) +bool CCID_CheckStatusNoError(uint8_t Status) { - return (status & 0xC0) == 0x0; + return (Status & 0xC0) == 0x0; } void CCID_Device_ProcessControlRequest(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) @@ -113,7 +113,7 @@ void CCID_Device_ProcessControlRequest(USB_ClassInfo_CCID_Device_t* const CCIDIn bool CCID_Device_ConfigureEndpoints(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) { - CCIDInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; + CCIDInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; CCIDInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; if (!(Endpoint_ConfigureEndpointTable(&CCIDInterfaceInfo->Config.DataINEndpoint, 1))) @@ -231,10 +231,11 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_ClearIN(); break; } + case CCID_PC_to_RDR_SetParameters: { uint8_t ProtocolNum = Endpoint_Read_8(); - uint8_t RFU = Endpoint_Read_16_LE(); + uint8_t RFU = Endpoint_Read_16_LE(); (void)RFU; @@ -244,14 +245,14 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ResponseParametersStatus->CCIDHeader.Slot = CCIDHeader.Slot; ResponseParametersStatus->CCIDHeader.Seq = CCIDHeader.Seq; - if(ProtocolNum == CCID_PROTOCOLNUM_T0) + if (ProtocolNum == CCID_PROTOCOLNUM_T0) { - if(CCIDHeader.Length * sizeof(uint8_t) == sizeof(USB_CCID_ProtocolData_T0_t)) + if (CCIDHeader.Length * sizeof(uint8_t) == sizeof(USB_CCID_ProtocolData_T0_t)) { - + Endpoint_Read_Stream_LE(RequestBuffer, CCIDHeader.Length * sizeof(uint8_t), NULL); Status = CALLBACK_CCID_SetParameters_T0(CCIDInterfaceInfo, CCIDHeader.Slot, &Error, (USB_CCID_ProtocolData_T0_t*) RequestBuffer); - if(CCID_CheckStatusNoError(Status)) + if (CCID_CheckStatusNoError(Status)) { ResponseParametersStatus->CCIDHeader.Length = CCIDHeader.Length; Status = CALLBACK_CCID_GetParameters_T0(CCIDInterfaceInfo, CCIDHeader.Slot, &Error, &ResponseParametersStatus->ProtocolNum, (USB_CCID_ProtocolData_T0_t*) &ResponseParametersStatus->ProtocolData); @@ -259,15 +260,16 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) } else { - //unexpected length + // Unexpected length Status = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_PRESENTANDACTIVE; } } else { ResponseParametersStatus->ProtocolNum = CCID_PROTOCOLNUM_T0; - //for now, we don't support T=1 protocol - Error = CCID_ERROR_PARAMETERS_PROTOCOL_NOT_SUPPORTED; + + // For now, we don't support T=1 protocol + Error = CCID_ERROR_PARAMETERS_PROTOCOL_NOT_SUPPORTED; Status = CCID_COMMANDSTATUS_ERROR | CCID_ICCSTATUS_PRESENTANDACTIVE; } @@ -281,6 +283,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_ClearIN(); break; } + case CCID_PC_to_RDR_GetParameters: { USB_CCID_RDR_to_PC_Parameters_t* ResponseParametersStatus = (USB_CCID_RDR_to_PC_Parameters_t*)&ResponseBuffer; @@ -301,6 +304,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_ClearIN(); break; } + case CCID_PC_to_RDR_XfrBlock: { uint8_t Bwi = Endpoint_Read_8(); @@ -312,7 +316,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_Read_Stream_LE(ReceivedBuffer, sizeof(ReceivedBuffer), NULL); - uint8_t ResponseDataLength = 0; + uint8_t ResponseDataLength = 0; USB_CCID_RDR_to_PC_DataBlock_t* ResponseBlock = (USB_CCID_RDR_to_PC_DataBlock_t*)&ResponseBuffer; ResponseBlock->CCIDHeader.MessageType = CCID_RDR_to_PC_DataBlock; @@ -327,7 +331,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) { ResponseBlock->CCIDHeader.Length = ResponseDataLength; } - else if(CCIDInterfaceInfo->State.Aborted) + else if (CCIDInterfaceInfo->State.Aborted) { Status = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_PRESENTANDACTIVE; Error = CCID_ERROR_CMD_ABORTED; @@ -379,6 +383,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); Endpoint_Write_Stream_LE(ResponseBuffer, sizeof(ResponseBuffer), NULL); Endpoint_ClearIN(); + break; } } } diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h index e6b774fda..05f487fa2 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h @@ -117,31 +117,31 @@ * (answer to reset) * * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. - * \param[in] slot The slot ID currently being powered on. - * \param[in,out] atr Pointer to an array containing the Power On ATR being sent to the device. - * \param[out] atrSize The size of the ATR being sent (up to 15 bytes maximum). - * \param[out] error The result of the operation, or error. + * \param[in] Slot The slot ID currently being powered on. + * \param[in,out] Atr Pointer to an array containing the Power On ATR being sent to the device. + * \param[out] AtrSize The size of the ATR being sent (up to 15 bytes maximum). + * \param[out] Error The result of the operation, or error. * * \return The command result code. */ uint8_t CALLBACK_CCID_IccPowerOn(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t slot, - uint8_t* const atr, - uint8_t* const atrSize, - uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); + uint8_t Slot, + uint8_t* const Atr, + uint8_t* const AtrSize, + uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_IccPowerOff CCID message * Turns off the ICC * * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. - * \param[in] slot The slot ID currently being powered off. - * \param[out] error The result of the operation, or error. + * \param[in] Slot The slot ID currently being powered off. + * \param[out] Error The result of the operation, or error. * * \return The command result code. */ uint8_t CALLBACK_CCID_IccPowerOff(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t slot, - uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); + uint8_t Slot, + uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_GetSlotStatus CCID message * Retrieves the current status of a given slot @@ -153,78 +153,78 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t slot, - uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); + uint8_t Slot, + uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_SetParameters CCID message for T=0 * Sets the current parameters of a given slot * * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration, state and protocol data. - * \param[in] slot The slot ID from which we want to retrieve the status. - * \param[out] error The result of the operation, or error. - * \param[out] t0 Pointer to a buffer containing the new parameters + * \param[in] Slot The slot ID from which we want to retrieve the status. + * \param[out] Error The result of the operation, or error. + * \param[out] T0 Pointer to a buffer containing the new parameters * * \return The command result code. */ uint8_t CALLBACK_CCID_SetParameters_T0(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t slot, - uint8_t* const error, - USB_CCID_ProtocolData_T0_t* const t0); + uint8_t Slot, + uint8_t* const Error, + USB_CCID_ProtocolData_T0_t* const T0); /** CCID class driver callback for PC_TO_RDR_SetParameters CCID message for T=0 * Retrieves the current parameters of a given slot * * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration, state and protocol data. - * \param[in] slot The slot ID from which we want to retrieve the status. - * \param[out] error The result of the operation, or error. - * \param[out] t0 Pointer to a buffer where the parameters will be returned + * \param[in] Slot The slot ID from which we want to retrieve the status. + * \param[out] Error The result of the operation, or error. + * \param[out] T0 Pointer to a buffer where the parameters will be returned * * \return The command result code. */ uint8_t CALLBACK_CCID_GetParameters_T0(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t slot, - uint8_t* const error, + uint8_t Slot, + uint8_t* const Error, uint8_t* const ProtocolNum, - USB_CCID_ProtocolData_T0_t* const t0); + USB_CCID_ProtocolData_T0_t* const T0); /** CCID class driver callback for PC_TO_RDR_XfrBlock CCID message - * Send a block of bytes from the host to a slot in the device + * Send a block of bytes from the host to a slot in the device * and also received a block of bytes as a response - * + * * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. - * \param[in] slot The slot ID from which we want to retrieve the status. - * \param[in] receivedBuffer Pointer to an array holding the received block of bytes - * \param[in] receivedBufferSize The size of the received block of bytes - * \param[out] sendBuffer Pointer to a buffer which will hold the bytes being sent back to the host - * \param[out] sentBufferSize The size of the block of bytes being sent back to the host - * \param[out] error The result of the operation, or error. + * \param[in] Slot The slot ID from which we want to retrieve the status. + * \param[in] ReceivedBuffer Pointer to an array holding the received block of bytes + * \param[in] ReceivedBufferSize The size of the received block of bytes + * \param[out] SendBuffer Pointer to a buffer which will hold the bytes being sent back to the host + * \param[out] SentBufferSize The size of the block of bytes being sent back to the host + * \param[out] Error The result of the operation, or error. * * \return The command result code. */ uint8_t CALLBACK_CCID_XfrBlock(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t slot, - uint8_t* const receivedBuffer, - uint8_t receivedBufferSize, - uint8_t* const sendBuffer, - uint8_t* const sentBufferSize, - uint8_t* const error); + uint8_t Slot, + uint8_t* const ReceivedBuffer, + uint8_t ReceivedBufferSize, + uint8_t* const SendBuffer, + uint8_t* const SentBufferSize, + uint8_t* const Error); /** CCID class driver callback for CCID_PC_to_RDR_Abort CCID message * Aborts a BULK out message previously sent to a slot * * \param[in,out] CCIDInterfaceInfo Pointer to a structure containing a CCID Class configuration and state. - * \param[in] slot The slot ID to where the message being aborted was sent to. - * \param[in] seq The current sequence number for this message. Must be checked against + * \param[in] Slot The slot ID to where the message being aborted was sent to. + * \param[in] Seq The current sequence number for this message. Must be checked against * the current abort message being sent at the control pipe. - * \param[out] error The result of the operation, or error. + * \param[out] Error The result of the operation, or error. * * \return The command result code. */ uint8_t CALLBACK_CCID_Abort(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t slot, - uint8_t seq, - uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); + uint8_t Slot, + uint8_t Seq, + uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); #endif -- cgit v1.2.3 From f469eb7745b52029d57636334b2e3f4e511bc968 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 6 Aug 2018 20:04:01 +1000 Subject: Add const qualifiers to class driver callback parameters, fix parameter naming. --- LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h index 05f487fa2..e29ccef08 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h @@ -125,7 +125,7 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_IccPowerOn(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t Slot, + const uint8_t Slot, uint8_t* const Atr, uint8_t* const AtrSize, uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); @@ -140,7 +140,7 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_IccPowerOff(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t Slot, + const uint8_t Slot, uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_GetSlotStatus CCID message @@ -153,7 +153,7 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t Slot, + const uint8_t Slot, uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); @@ -168,9 +168,9 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_SetParameters_T0(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t Slot, + const uint8_t Slot, uint8_t* const Error, - USB_CCID_ProtocolData_T0_t* const T0); + USB_CCID_ProtocolData_T0_t* const T0) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_SetParameters CCID message for T=0 * Retrieves the current parameters of a given slot @@ -183,10 +183,10 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_GetParameters_T0(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t Slot, + const uint8_t Slot, uint8_t* const Error, uint8_t* const ProtocolNum, - USB_CCID_ProtocolData_T0_t* const T0); + USB_CCID_ProtocolData_T0_t* const T0) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for PC_TO_RDR_XfrBlock CCID message * Send a block of bytes from the host to a slot in the device @@ -203,12 +203,12 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_XfrBlock(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t Slot, - uint8_t* const ReceivedBuffer, - uint8_t ReceivedBufferSize, + const uint8_t Slot, + const uint8_t* ReceivedBuffer, + const uint8_t ReceivedBufferSize, uint8_t* const SendBuffer, uint8_t* const SentBufferSize, - uint8_t* const Error); + uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); /** CCID class driver callback for CCID_PC_to_RDR_Abort CCID message * Aborts a BULK out message previously sent to a slot @@ -222,8 +222,8 @@ * \return The command result code. */ uint8_t CALLBACK_CCID_Abort(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, - uint8_t Slot, - uint8_t Seq, + const uint8_t Slot, + const uint8_t Seq, uint8_t* const Error) ATTR_NON_NULL_PTR_ARG(1); -- cgit v1.2.3