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