Build: Fix incorrect build target for Ubuntu CI builds.
[pub/USBasp.git] / LUFA / Drivers / USB / Class / Device / CCIDClassDevice.c
index 11c20f0..02eb57c 100644 (file)
@@ -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,9 +232,130 @@ 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();
+                               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;
@@ -238,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;
@@ -250,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;
                        }
                }
        }