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

Merge pull request #135 from kidbomb/feature-ccid-get-set-parameters

CCID: Support for Get and Set Parameters
parents 941bc147 a877ffb6
...@@ -193,7 +193,7 @@ uint8_t CALLBACK_CCID_IccPowerOff(USB_ClassInfo_CCID_Device_t* const CCIDInterfa ...@@ -193,7 +193,7 @@ uint8_t CALLBACK_CCID_IccPowerOff(USB_ClassInfo_CCID_Device_t* const CCIDInterfa
} }
} }
/** Event handler for the CCID_PC_to_RDR_GetSlotStatus. THis message is sent to the device /** Event handler for the CCID_PC_to_RDR_GetSlotStatus. This message is sent to the device
* whenever an application at the host wants to the get the current slot status * whenever an application at the host wants to the get the current slot status
* *
*/ */
...@@ -213,6 +213,58 @@ uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInter ...@@ -213,6 +213,58 @@ uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInter
} }
} }
/** Event handler for the CCID_PC_to_RDR_SetParameters when T=0. This message is sent to
* the device whenever an application at the host wants to set the
* parameters for a given slot.
*/
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)
{
if (slot == 0)
{
//set parameters
memcpy(&CCIDInterfaceInfo->ProtocolData, t0, sizeof(USB_CCID_ProtocolData_T0_t));
*error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
}
else
{
*error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
}
}
/** Event handler for the CCID_PC_to_RDR_GetParameters when T=0. This message is sent to
* the device whenever an application at the host wants to get the current
* parameters for a given slot.
*/
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)
{
if (slot == 0)
{
*ProtocolNum = CCID_PROTOCOLNUM_T0;
memcpy(t0, &CCIDInterfaceInfo->ProtocolData, sizeof(USB_CCID_ProtocolData_T0_t));
*ProtocolNum = CCID_PROTOCOLNUM_T0;
*error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
}
else
{
*error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
}
}
/** Event handler for the CCID_PC_to_RDR_XfrBlock. This message is sent to the device /** 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 * 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 * THe device reply back with an array of bytes
......
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
static bool Aborted; static bool Aborted;
static uint8_t AbortedSeq; static uint8_t AbortedSeq;
static USB_CCID_ProtocolData_T0_t ProtocolData;
/** Main program entry point. This routine configures the hardware required by the application, then /** Main program entry point. This routine configures the hardware required by the application, then
...@@ -59,6 +61,12 @@ static uint8_t AbortedSeq; ...@@ -59,6 +61,12 @@ static uint8_t AbortedSeq;
*/ */
int main(void) int main(void)
{ {
ProtocolData.FindexDindex = 0x11;
ProtocolData.TCCKST0 = 0x00;
ProtocolData.GuardTimeT0 = 0x00;
ProtocolData.WaitingIntegerT0 = 0x0A;
ProtocolData.ClockStop = 0x00;
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
...@@ -234,7 +242,7 @@ uint8_t CCID_IccPowerOff(uint8_t slot, ...@@ -234,7 +242,7 @@ uint8_t CCID_IccPowerOff(uint8_t slot,
} }
/** Event handler for the CCID_PC_to_RDR_GetSlotStatus. THis message is sent to /** Event handler for the CCID_PC_to_RDR_GetSlotStatus. THis message is sent to
* the device whenever an application at the host wants to the get the current * the device whenever an application at the host wants to get the current
* slot status. * slot status.
*/ */
uint8_t CCID_GetSlotStatus(uint8_t slot, uint8_t CCID_GetSlotStatus(uint8_t slot,
...@@ -251,6 +259,54 @@ uint8_t CCID_GetSlotStatus(uint8_t slot, ...@@ -251,6 +259,54 @@ uint8_t CCID_GetSlotStatus(uint8_t slot,
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT; return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
} }
} }
/** Event handler for the CCID_PC_to_RDR_SetParameters when T=0. This message is sent to
* the device whenever an application at the host wants to set the
* parameters for a given slot.
*/
uint8_t CCID_SetParameters_T0(uint8_t slot,
uint8_t* const error,
USB_CCID_ProtocolData_T0_t* const t0)
{
if (slot == 0)
{
//set parameters
memcpy(&ProtocolData, t0, sizeof(USB_CCID_ProtocolData_T0_t));
*error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
}
else
{
*error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
}
}
/** Event handler for the CCID_PC_to_RDR_GetParameters when T=0. This message is sent to
* the device whenever an application at the host wants to get the current
* parameters for a given slot.
*/
uint8_t CCID_GetParameters_T0(uint8_t slot,
uint8_t* const error,
uint8_t* ProtocolNum,
USB_CCID_ProtocolData_T0_t* const t0)
{
if (slot == 0)
{
*ProtocolNum = CCID_PROTOCOLNUM_T0;
memcpy(t0, &ProtocolData, sizeof(USB_CCID_ProtocolData_T0_t));
*ProtocolNum = CCID_PROTOCOLNUM_T0;
*error = CCID_ERROR_NO_ERROR;
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
}
else
{
*error = CCID_ERROR_SLOT_NOT_FOUND;
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
}
}
/** Event handler for the CCID_PC_to_RDR_XfrBlock. This message is sent to the device /** 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 * whenever an application at the host wants to send a block of bytes to the device
...@@ -421,7 +477,76 @@ void CCID_Task(void) ...@@ -421,7 +477,76 @@ void CCID_Task(void)
Endpoint_ClearIN(); Endpoint_ClearIN();
break; 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 = CCID_SetParameters_T0(CCIDHeader.Slot, &Error, (USB_CCID_ProtocolData_T0_t*) RequestBuffer);
if(CCID_CheckStatusNoError(Status))
{
ResponseParametersStatus->CCIDHeader.Length = CCIDHeader.Length;
Status = CCID_GetParameters_T0(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(CCID_IN_EPADDR);
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 = CCID_GetParameters_T0(CCIDHeader.Slot, &Error, &ResponseParametersStatus->ProtocolNum, (USB_CCID_ProtocolData_T0_t*) &ResponseParametersStatus->ProtocolData);
ResponseParametersStatus->Status = Status;
ResponseParametersStatus->Error = Error;
Endpoint_ClearOUT();
Endpoint_SelectEndpoint(CCID_IN_EPADDR);
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: case CCID_PC_to_RDR_XfrBlock:
{ {
uint8_t Bwi = Endpoint_Read_8(); uint8_t Bwi = Endpoint_Read_8();
...@@ -441,7 +566,7 @@ void CCID_Task(void) ...@@ -441,7 +566,7 @@ void CCID_Task(void)
ResponseBlock->ChainParam = 0; ResponseBlock->ChainParam = 0;
Status = CCID_XfrBlock(CCIDHeader.Slot, RequestBuffer, CCIDHeader.Length, &ResponseBlock->Data, &ResponseDataLength, &Error); Status = CCID_XfrBlock(CCIDHeader.Slot, RequestBuffer, CCIDHeader.Length, (uint8_t*) &ResponseBlock->Data, &ResponseDataLength, &Error);
if (CCID_CheckStatusNoError(Status) && !Aborted) if (CCID_CheckStatusNoError(Status) && !Aborted)
{ {
......
...@@ -23,10 +23,12 @@ var sprintf = require('sprintf'); ...@@ -23,10 +23,12 @@ var sprintf = require('sprintf');
var deviceVid = 0x03EB; var deviceVid = 0x03EB;
var devicePid = 0x206E; var devicePid = 0x206E;
var CCID_PC_to_RDR_SetParameters = 0x61;
var CCID_PC_to_RDR_GetParameters = 0x6C;
var CCID_PC_to_RDR_IccPowerOn = 0x62; var CCID_PC_to_RDR_IccPowerOn = 0x62;
var CCID_PC_to_RDR_IccPowerOff = 0x63; var CCID_PC_to_RDR_IccPowerOff = 0x63;
var CCID_PC_to_RDR_GetSlotStatus = 0x65; var CCID_PC_to_RDR_GetSlotStatus = 0x65;
var CCID_PC_to_RDR_XfrBlock = 0x6f; var CCID_PC_to_RDR_XfrBlock = 0x6f;
function getAndInitCcidDeviceAndInterface() function getAndInitCcidDeviceAndInterface()
{ {
...@@ -72,6 +74,30 @@ function write(ccidInterface, message, callback) ...@@ -72,6 +74,30 @@ function write(ccidInterface, message, callback)
//CCID functions //CCID functions
function GetParametersMessage(slot, seq, protocolNum, t0Params)
{
return [
CCID_PC_to_RDR_GetParameters, //message type
0, 0, 0, 0, //length
slot,
seq,
0, 0, 0 //RFU
];
}
function SetParametersMessage(slot, seq, protocolNum, t0Params)
{
return [
CCID_PC_to_RDR_SetParameters, //message type
t0Params.length, 0, 0, 0, //length
slot,
seq,
protocolNum,
0, 0 //RFU
].concat(t0Params);
}
function IccPowerOnMessage(slot, seq) function IccPowerOnMessage(slot, seq)
{ {
return [ return [
...@@ -119,9 +145,9 @@ function XfrBlockMessage(slot, seq, apdu) ...@@ -119,9 +145,9 @@ function XfrBlockMessage(slot, seq, apdu)
} }
function startTest() function testCcidMessages()
{ {
async.series([ return [
function(callback) { function(callback) {
write(ccidInterface, new Buffer(IccPowerOnMessage(0, 1)), callback); write(ccidInterface, new Buffer(IccPowerOnMessage(0, 1)), callback);
}, },
...@@ -141,12 +167,26 @@ function startTest() ...@@ -141,12 +167,26 @@ function startTest()
read(ccidInterface, 10, callback); read(ccidInterface, 10, callback);
}, },
function(callback) { function(callback) {
write(ccidInterface, new Buffer(XfrBlockMessage(0, 4, [0x0, 0xFD, 0x0, 0x0, 0x0])), callback); write(ccidInterface, new Buffer(SetParametersMessage(0, 4, 0, [0x11, 0x00, 0x00, 0x0a, 0x00])), callback);
}, },
function(callback) { function(callback) {
read(ccidInterface, 10 + 2, callback); //must return 82 05 00 00 00 00 04 00 80 00 11 00 00 0a 00
} read(ccidInterface, 30, callback);
]); },
function(callback) {
write(ccidInterface, new Buffer(GetParametersMessage(0, 5, 0)), callback);
},
function(callback) {
//must return 82 05 00 00 00 00 04 00 80 00 11 00 00 0a 00
read(ccidInterface, 30, callback);
}];
}
function startTest()
{
async.series([]
.concat(testCcidMessages())
);
} }
var ccidDeviceAndInterface = getAndInitCcidDeviceAndInterface(); var ccidDeviceAndInterface = getAndInitCcidDeviceAndInterface();
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#define CCID_ICCSTATUS_NOICCPRESENT (1 << 1) #define CCID_ICCSTATUS_NOICCPRESENT (1 << 1)
#define CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR 0 #define CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR 0
#define CCID_COMMANDSTATUS_ERROR 1
#define CCID_COMMANDSTATUS_FAILED (1 << 6) #define CCID_COMMANDSTATUS_FAILED (1 << 6)
#define CCID_COMMANDSTATUS_TIMEEXTENSIONREQUESTED (2 << 6) #define CCID_COMMANDSTATUS_TIMEEXTENSIONREQUESTED (2 << 6)
#define CCID_COMMANDSTATUS_RFU (3 << 6) #define CCID_COMMANDSTATUS_RFU (3 << 6)
...@@ -91,6 +92,8 @@ ...@@ -91,6 +92,8 @@
#define CCID_ERROR_CMD_ABORTED 0xFF #define CCID_ERROR_CMD_ABORTED 0xFF
#define CCID_ERROR_CMD_NOT_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_ERROR_SLOT_NOT_FOUND 5
#define CCID_DESCRIPTOR_CLOCK_KHZ(khz) (khz) #define CCID_DESCRIPTOR_CLOCK_KHZ(khz) (khz)
......
...@@ -231,7 +231,76 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo) ...@@ -231,7 +231,76 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
Endpoint_ClearIN(); Endpoint_ClearIN();
break; 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: case CCID_PC_to_RDR_XfrBlock:
{ {
uint8_t Bwi = Endpoint_Read_8(); uint8_t Bwi = Endpoint_Read_8();
......
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
} State; /**< State data for the USB class interface within the device. All elements in this section } 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. * are reset to their defaults when the interface is enumerated.
*/ */
USB_CCID_ProtocolData_T0_t ProtocolData;
} USB_ClassInfo_CCID_Device_t; } USB_ClassInfo_CCID_Device_t;
/* Function Prototypes: */ /* Function Prototypes: */
...@@ -155,6 +156,38 @@ ...@@ -155,6 +156,38 @@
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_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 /** 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 * Send a block of bytes from the host to a slot in the device
* and also received a block of bytes as a response * and also received a block of bytes as a response
......
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