Unverified Commit 941bc147 authored by Dean Camera's avatar Dean Camera Committed by GitHub
Browse files

Merge pull request #131 from kidbomb/feature-ccid-xfrblock

CCID: Add support for PC-to-Reader XfrBlock message
parents bc57f4ea 1e9e7bc8
...@@ -213,6 +213,34 @@ uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInter ...@@ -213,6 +213,34 @@ uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInter
} }
} }
/** Event handler for the CCID_PC_to_RDR_XfrBlock. This message is sent to the device
* whenever an application at the host wants to send a block of bytes to the device
* THe device reply back with an array of bytes
*/
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)
{
if (slot < CCID_Interface.Config.TotalSlots)
{
uint8_t okResponse[2] = {0x90, 0x00};
memcpy(sendBuffer, okResponse, sizeof(okResponse));
*sentBufferSize = sizeof(okResponse);
*error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_NOICCPRESENT;
}
else
{
*error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
}
}
uint8_t CALLBACK_CCID_Abort(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, uint8_t CALLBACK_CCID_Abort(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo,
uint8_t slot, uint8_t slot,
uint8_t seq, uint8_t seq,
......
...@@ -86,6 +86,13 @@ ...@@ -86,6 +86,13 @@
uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo,
uint8_t slot, uint8_t slot,
uint8_t* const error); uint8_t* const error);
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 CALLBACK_CCID_Abort(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo, uint8_t CALLBACK_CCID_Abort(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo,
uint8_t slot, uint8_t slot,
uint8_t seq, uint8_t seq,
......
...@@ -117,8 +117,8 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = ...@@ -117,8 +117,8 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.MaxIFSD = 2038, .MaxIFSD = 2038,
.SynchProtocols = 0, .SynchProtocols = 0,
.Mechanical = 0, .Mechanical = 0,
.Features = 0x0400fe, .Features = CCID_Features_ExchangeLevel_ShortAPDU | CCID_Features_Auto_ParameterConfiguration| CCID_Features_Auto_ICCActivation | CCID_Features_Auto_VoltageSelection,
.MaxCCIDMessageLength = 0x0c00, .MaxCCIDMessageLength = CCID_EPSIZE,
.ClassGetResponse = 0xff, .ClassGetResponse = 0xff,
.ClassEnvelope = 0xff, .ClassEnvelope = 0xff,
.LcdLayout = 0, .LcdLayout = 0,
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
/** Endpoint address of the CCID data OUT endpoint, for host-to-device data transfers. */ /** Endpoint address of the CCID data OUT endpoint, for host-to-device data transfers. */
#define CCID_OUT_EPADDR (ENDPOINT_DIR_OUT | 1) #define CCID_OUT_EPADDR (ENDPOINT_DIR_OUT | 1)
/** Endpoint size in bytes of the Audio isochronous streaming data IN and OUT endpoints. */ /** Endpoint size in bytes of the CCID data being sent between IN and OUT endpoints. */
#define CCID_EPSIZE 64 #define CCID_EPSIZE 64
......
...@@ -252,6 +252,33 @@ uint8_t CCID_GetSlotStatus(uint8_t slot, ...@@ -252,6 +252,33 @@ uint8_t CCID_GetSlotStatus(uint8_t slot,
} }
} }
/** Event handler for the CCID_PC_to_RDR_XfrBlock. This message is sent to the device
* whenever an application at the host wants to send a block of bytes to the device
* THe device reply back with an array of bytes
*/
uint8_t CCID_XfrBlock(uint8_t slot,
uint8_t* const receivedBuffer,
uint8_t receivedBufferSize,
uint8_t* const sendBuffer,
uint8_t* const sentBufferSize,
uint8_t* const error)
{
if (slot == 0)
{
uint8_t okResponse[2] = {0x90, 0x00};
memcpy(sendBuffer, okResponse, sizeof(okResponse));
*sentBufferSize = sizeof(okResponse);
*error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_NOICCPRESENT;
}
else
{
*error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
}
}
/** Event handler for the CCID_PC_to_RDR_ABort message. This message is sent to the device /** Event handler for the CCID_PC_to_RDR_ABort message. This message is sent to the device
* whenever an application wants to abort the current operation. A previous CCID_ABORT * whenever an application wants to abort the current operation. A previous CCID_ABORT
* control message has to be sent before this one in order to start the abort operation. * control message has to be sent before this one in order to start the abort operation.
...@@ -293,7 +320,8 @@ void CCID_Task(void) ...@@ -293,7 +320,8 @@ void CCID_Task(void)
{ {
Endpoint_SelectEndpoint(CCID_OUT_EPADDR); Endpoint_SelectEndpoint(CCID_OUT_EPADDR);
uint8_t BlockBuffer[0x20]; uint8_t RequestBuffer[CCID_EPSIZE - sizeof(USB_CCID_BulkMessage_Header_t)];
uint8_t ResponseBuffer[CCID_EPSIZE];
Aborted = false; Aborted = false;
AbortedSeq = -1; AbortedSeq = -1;
...@@ -313,7 +341,7 @@ void CCID_Task(void) ...@@ -313,7 +341,7 @@ void CCID_Task(void)
case CCID_PC_to_RDR_IccPowerOn: case CCID_PC_to_RDR_IccPowerOn:
{ {
uint8_t AtrLength; 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.MessageType = CCID_RDR_to_PC_DataBlock;
ResponseATR->CCIDHeader.Slot = CCIDHeader.Slot; ResponseATR->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -350,7 +378,7 @@ void CCID_Task(void) ...@@ -350,7 +378,7 @@ void CCID_Task(void)
case CCID_PC_to_RDR_IccPowerOff: 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.MessageType = CCID_RDR_to_PC_SlotStatus;
ResponsePowerOff->CCIDHeader.Length = 0; ResponsePowerOff->CCIDHeader.Length = 0;
ResponsePowerOff->CCIDHeader.Slot = CCIDHeader.Slot; ResponsePowerOff->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -373,7 +401,7 @@ void CCID_Task(void) ...@@ -373,7 +401,7 @@ void CCID_Task(void)
case CCID_PC_to_RDR_GetSlotStatus: 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.MessageType = CCID_RDR_to_PC_SlotStatus;
ResponseSlotStatus->CCIDHeader.Length = 0; ResponseSlotStatus->CCIDHeader.Length = 0;
ResponseSlotStatus->CCIDHeader.Slot = CCIDHeader.Slot; ResponseSlotStatus->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -394,9 +422,56 @@ void CCID_Task(void) ...@@ -394,9 +422,56 @@ void CCID_Task(void)
break; break;
} }
case CCID_PC_to_RDR_XfrBlock:
{
uint8_t Bwi = Endpoint_Read_8();
uint16_t LevelParameter = Endpoint_Read_16_LE();
(void)Bwi;
(void)LevelParameter;
Endpoint_Read_Stream_LE(RequestBuffer, CCIDHeader.Length * sizeof(uint8_t), 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 = CCID_XfrBlock(CCIDHeader.Slot, RequestBuffer, CCIDHeader.Length, &ResponseBlock->Data, &ResponseDataLength, &Error);
if (CCID_CheckStatusNoError(Status) && !Aborted)
{
ResponseBlock->CCIDHeader.Length = ResponseDataLength;
}
else if (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(CCID_IN_EPADDR);
Endpoint_Write_Stream_LE(ResponseBlock, sizeof(USB_CCID_RDR_to_PC_DataBlock_t) + ResponseDataLength, NULL);
Endpoint_ClearIN();
break;
}
case CCID_PC_to_RDR_Abort: 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.MessageType = CCID_RDR_to_PC_SlotStatus;
ResponseAbort->CCIDHeader.Length = 0; ResponseAbort->CCIDHeader.Length = 0;
ResponseAbort->CCIDHeader.Slot = CCIDHeader.Slot; ResponseAbort->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -418,10 +493,10 @@ void CCID_Task(void) ...@@ -418,10 +493,10 @@ void CCID_Task(void)
} }
default: default:
{ {
memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); memset(ResponseBuffer, 0x00, sizeof(ResponseBuffer));
Endpoint_SelectEndpoint(CCID_IN_EPADDR); Endpoint_SelectEndpoint(CCID_IN_EPADDR);
Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); Endpoint_Write_Stream_LE(ResponseBuffer, sizeof(ResponseBuffer), NULL);
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
} }
......
...@@ -119,8 +119,8 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = ...@@ -119,8 +119,8 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.MaxIFSD = 2038, .MaxIFSD = 2038,
.SynchProtocols = 0, .SynchProtocols = 0,
.Mechanical = 0, .Mechanical = 0,
.Features = 0x0400fe, .Features = CCID_Features_ExchangeLevel_ShortAPDU | CCID_Features_Auto_ParameterConfiguration| CCID_Features_Auto_ICCActivation | CCID_Features_Auto_VoltageSelection,
.MaxCCIDMessageLength = 0x0c00, .MaxCCIDMessageLength = CCID_EPSIZE,
.ClassGetResponse = 0xff, .ClassGetResponse = 0xff,
.ClassEnvelope = 0xff, .ClassEnvelope = 0xff,
.LcdLayout = 0, .LcdLayout = 0,
......
...@@ -106,17 +106,16 @@ function GetSlotStatusMessage(slot, seq) ...@@ -106,17 +106,16 @@ function GetSlotStatusMessage(slot, seq)
]; ];
} }
function XfrBlockMessage(slot, seq) function XfrBlockMessage(slot, seq, apdu)
{ {
return [ return [
CCID_PC_to_RDR_XfrBlock, //message type CCID_PC_to_RDR_XfrBlock, //message type
5, 0, 0, 0, //length (05) apdu.length, 0, 0, 0, //length: only for < 0xFF
slot, slot,
seq, seq,
0, //BWI 0, //BWI
0, 0, //level parameter 0, 0 //level parameter
0, 0xfd, 0, 0, 0 //message ].concat(apdu);
];
} }
...@@ -140,6 +139,12 @@ function startTest() ...@@ -140,6 +139,12 @@ function startTest()
}, },
function(callback) { function(callback) {
read(ccidInterface, 10, callback); read(ccidInterface, 10, callback);
},
function(callback) {
write(ccidInterface, new Buffer(XfrBlockMessage(0, 4, [0x0, 0xFD, 0x0, 0x0, 0x0])), callback);
},
function(callback) {
read(ccidInterface, 10 + 2, callback);
} }
]); ]);
} }
......
...@@ -153,6 +153,26 @@ ...@@ -153,6 +153,26 @@
CCID_DTYPE_Functional = 0x21, /**< CCID class specific Interface functional descriptor. */ 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: */ /* Type Defines: */
typedef struct typedef struct
{ {
......
...@@ -129,7 +129,9 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -129,7 +129,9 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
{ {
Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataOUTEndpoint.Address); 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.Aborted = false;
CCIDInterfaceInfo->State.AbortedSeq = -1; CCIDInterfaceInfo->State.AbortedSeq = -1;
...@@ -149,7 +151,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -149,7 +151,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
case CCID_PC_to_RDR_IccPowerOn: case CCID_PC_to_RDR_IccPowerOn:
{ {
uint8_t AtrLength; 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.MessageType = CCID_RDR_to_PC_DataBlock;
ResponseATR->CCIDHeader.Slot = CCIDHeader.Slot; ResponseATR->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -186,7 +188,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -186,7 +188,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
case CCID_PC_to_RDR_IccPowerOff: 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.MessageType = CCID_RDR_to_PC_SlotStatus;
ResponsePowerOff->CCIDHeader.Length = 0; ResponsePowerOff->CCIDHeader.Length = 0;
ResponsePowerOff->CCIDHeader.Slot = CCIDHeader.Slot; ResponsePowerOff->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -209,7 +211,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -209,7 +211,7 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
case CCID_PC_to_RDR_GetSlotStatus: 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.MessageType = CCID_RDR_to_PC_SlotStatus;
ResponseSlotStatus->CCIDHeader.Length = 0; ResponseSlotStatus->CCIDHeader.Length = 0;
ResponseSlotStatus->CCIDHeader.Slot = CCIDHeader.Slot; ResponseSlotStatus->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -230,9 +232,57 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -230,9 +232,57 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
break; 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: 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.MessageType = CCID_RDR_to_PC_SlotStatus;
ResponseAbort->CCIDHeader.Length = 0; ResponseAbort->CCIDHeader.Length = 0;
ResponseAbort->CCIDHeader.Slot = CCIDHeader.Slot; ResponseAbort->CCIDHeader.Slot = CCIDHeader.Slot;
...@@ -255,10 +305,10 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -255,10 +305,10 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
default: default:
{ {
memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); memset(ResponseBuffer, 0x00, sizeof(ResponseBuffer));
Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address); Endpoint_SelectEndpoint(CCIDInterfaceInfo->Config.DataINEndpoint.Address);
Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); Endpoint_Write_Stream_LE(ResponseBuffer, sizeof(ResponseBuffer), NULL);
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
} }
......
...@@ -155,6 +155,28 @@ ...@@ -155,6 +155,28 @@
uint8_t slot, uint8_t slot,
uint8_t* const error) ATTR_NON_NULL_PTR_ARG(1); 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 /** CCID class driver callback for CCID_PC_to_RDR_Abort CCID message
* Aborts a BULK out message previously sent to a slot * Aborts a BULK out message previously sent to a slot
* *
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment