X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/fc371d0d0e3a60b06dec862e37612375860c41d5..77c0786f90ce57651d9039b9dedde0e9a3c9da9d:/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c diff --git a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c index edc125779..02eb57c07 100644 --- a/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c +++ b/LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c @@ -1,14 +1,14 @@ /* LUFA Library - Copyright (C) Dean Camera, 2018. + Copyright (C) Dean Camera, 2019. 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) + Copyright 2019 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2019 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 @@ -39,9 +39,9 @@ #include "CCIDClassDevice.h" -bool CCID_CheckStatusNoError(int 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) @@ -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)) @@ -111,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))) @@ -127,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; @@ -147,14 +151,14 @@ 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; 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) { @@ -184,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; @@ -192,7 +196,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; @@ -207,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; @@ -215,7 +219,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; @@ -228,6 +232,79 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) 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(); @@ -239,33 +316,30 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_Read_Stream_LE(ReceivedBuffer, sizeof(ReceivedBuffer), NULL); - uint8_t SendBuffer[0x2] = {0x90, 0x00}; - uint8_t SendLength = sizeof(SendBuffer); + uint8_t ResponseDataLength = 0; - USB_CCID_RDR_to_PC_DataBlock_t* ResponseBlock = (USB_CCID_RDR_to_PC_DataBlock_t*)&BlockBuffer; + 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; - //TODO: Callback - Status = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE; + 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 = SendLength; - memcpy(&ResponseBlock->Data, SendBuffer, SendLength); + 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; - SendLength = 0; + ResponseDataLength = 0; } else { - SendLength = 0; + ResponseDataLength = 0; } ResponseBlock->Status = Status; @@ -274,14 +348,14 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_ClearOUT(); Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); - Endpoint_Write_Stream_LE(ResponseBlock, sizeof(USB_CCID_RDR_to_PC_DataBlock_t) + SendLength, NULL); + 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; @@ -289,7 +363,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; @@ -301,13 +375,15 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) Endpoint_ClearIN(); break; } + 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(); + break; } } }