Unverified Commit 8e590e6c authored by Dean Camera's avatar Dean Camera Committed by GitHub
Browse files

Merge pull request #126 from kidbomb/feature-ccid

CCID: Multiple Low level and Class driver changes.
parents fc371d0d ded673ec
...@@ -158,19 +158,19 @@ void EVENT_USB_Device_ControlRequest(void) ...@@ -158,19 +158,19 @@ void EVENT_USB_Device_ControlRequest(void)
* THe slot must reply back with a recognizable ATR (answer to reset) * THe slot must reply back with a recognizable ATR (answer to reset)
*/ */
uint8_t CALLBACK_CCID_IccPowerOn(uint8_t slot, uint8_t CALLBACK_CCID_IccPowerOn(uint8_t slot,
uint8_t* attr, uint8_t* atr,
uint8_t* attrSize, uint8_t* attrSize,
uint8_t* error) uint8_t* error)
{ {
if (slot < CCID_Interface.Config.TotalSlots) if (slot < CCID_Interface.Config.TotalSlots)
{ {
Iso7816_CreateSimpleAtr(attr, attrSize); Iso7816_CreateSimpleAtr(atr, attrSize);
*error = CCID_ERROR_NO_ERROR; *error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE; return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
} }
*error = CCID_ERROR_SLOT_NOT_FOUND; *error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT; return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
} }
/** Event handler for the CCID_PC_to_RDR_IccPowerOff message. This message is sent to the device /** Event handler for the CCID_PC_to_RDR_IccPowerOff message. This message is sent to the device
...@@ -186,7 +186,7 @@ uint8_t CALLBACK_CCID_IccPowerOff(uint8_t slot, uint8_t* error) ...@@ -186,7 +186,7 @@ uint8_t CALLBACK_CCID_IccPowerOff(uint8_t slot, uint8_t* error)
else else
{ {
*error = CCID_ERROR_SLOT_NOT_FOUND; *error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT; return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
} }
} }
...@@ -204,41 +204,13 @@ uint8_t CALLBACK_CCID_GetSlotStatus(uint8_t slot, uint8_t* error) ...@@ -204,41 +204,13 @@ uint8_t CALLBACK_CCID_GetSlotStatus(uint8_t slot, uint8_t* error)
else else
{ {
*error = CCID_ERROR_SLOT_NOT_FOUND; *error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT; return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
}
}
/** 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(uint8_t slot,
uint8_t* error,
uint8_t* receivedBuffer,
uint8_t receivedBufferSize,
uint8_t* sendBuffer,
uint8_t* sentBufferSize)
{
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(uint8_t slot, uint8_t CALLBACK_CCID_Abort(uint8_t slot,
uint8_t seq, uint8_t seq,
uint8_t* error) uint8_t* error)
{ {
if (CCID_Interface.State.Aborted && slot == 0 && CCID_Interface.State.AbortedSeq == seq) if (CCID_Interface.State.Aborted && slot == 0 && CCID_Interface.State.AbortedSeq == seq)
{ {
......
...@@ -81,12 +81,6 @@ ...@@ -81,12 +81,6 @@
uint8_t* error); uint8_t* error);
uint8_t CALLBACK_CCID_IccPowerOff(uint8_t slot, 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_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 CALLBACK_CCID_Abort(uint8_t slot,
uint8_t seq, uint8_t seq,
uint8_t *error); uint8_t *error);
......
...@@ -197,13 +197,13 @@ void EVENT_USB_Device_ControlRequest(void) ...@@ -197,13 +197,13 @@ void EVENT_USB_Device_ControlRequest(void)
* THe slot must reply back with a recognizable ATR (answer to reset) * THe slot must reply back with a recognizable ATR (answer to reset)
*/ */
uint8_t CCID_IccPowerOn(uint8_t slot, uint8_t CCID_IccPowerOn(uint8_t slot,
uint8_t* attr, uint8_t* atr,
uint8_t* attrLength, uint8_t* atrLength,
uint8_t* error) uint8_t* error)
{ {
if (slot == 0) if (slot == 0)
{ {
Iso7816_CreateSimpleAttr(attr, attrLength); Iso7816_CreateSimpleAtr(atr, atrLength);
*error = CCID_ERROR_NO_ERROR; *error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE; return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
...@@ -394,57 +394,6 @@ void CCID_Task(void) ...@@ -394,57 +394,6 @@ 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();
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) && !Aborted)
{
ResponseBlock->CCIDHeader.Length = SendLength;
memcpy(&ResponseBlock->Data, SendBuffer, SendLength);
}
else if (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(CCID_IN_EPADDR);
Endpoint_Write_Stream_LE(ResponseBlock, sizeof(USB_CCID_RDR_to_PC_DataBlock_t) + SendLength, 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*)&BlockBuffer;
......
...@@ -140,12 +140,6 @@ function startTest() ...@@ -140,12 +140,6 @@ function startTest()
}, },
function(callback) { function(callback) {
read(ccidInterface, 10, callback); read(ccidInterface, 10, callback);
},
function(callback) {
write(ccidInterface, new Buffer(XfrBlockMessage(0, 4)), callback);
},
function(callback) {
read(ccidInterface, 10 + 2, callback);
} }
]); ]);
} }
......
...@@ -31,17 +31,17 @@ ...@@ -31,17 +31,17 @@
#include "Iso7816.h" #include "Iso7816.h"
void Iso7816_CreateSimpleAttr(uint8_t* attr, uint8_t* attrLength) void Iso7816_CreateSimpleAtr(uint8_t* atr, uint8_t* atrLength)
{ {
attr[0] = 0x3B; // TS: direct convention atr[0] = 0x3B; // TS: direct convention
uint8_t interfaceBytesPresence = 0; uint8_t interfaceBytesPresence = 0;
uint8_t historycalBytes[14] = "Lufa CCID Demo"; // Must be equal or less than 15 uint8_t historycalBytes[14] = "Lufa CCID Demo"; // Must be equal or less than 15
uint8_t historicalBytesLength = sizeof(historycalBytes); uint8_t historicalBytesLength = sizeof(historycalBytes);
attr[1] = (interfaceBytesPresence << 4) + historicalBytesLength; //TO atr[1] = (interfaceBytesPresence << 4) + historicalBytesLength; //TO
memcpy(attr + 2, historycalBytes, historicalBytesLength); memcpy(atr + 2, historycalBytes, historicalBytesLength);
*attrLength = historicalBytesLength + 2; *atrLength = historicalBytesLength + 2;
} }
...@@ -40,6 +40,6 @@ ...@@ -40,6 +40,6 @@
#include <stdlib.h> #include <stdlib.h>
/* Function Prototypes: */ /* Function Prototypes: */
void Iso7816_CreateSimpleAttr(uint8_t* attr, uint8_t* attrLength); void Iso7816_CreateSimpleAtr(uint8_t* atr, uint8_t* atrLength);
#endif #endif
...@@ -228,57 +228,6 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -228,57 +228,6 @@ 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 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: 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*)&BlockBuffer;
......
...@@ -111,14 +111,49 @@ ...@@ -111,14 +111,49 @@
*/ */
void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); 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); 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); 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_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); uint8_t CALLBACK_CCID_Abort(uint8_t slot, uint8_t seq, uint8_t* error);
......
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