}
}
-/** 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
*
*/
}
}
+/** 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
* 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
static bool Aborted;
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
*/
int main(void)
{
+ ProtocolData.FindexDindex = 0x11;
+ ProtocolData.TCCKST0 = 0x00;
+ ProtocolData.GuardTimeT0 = 0x00;
+ ProtocolData.WaitingIntegerT0 = 0x0A;
+ ProtocolData.ClockStop = 0x00;
+
SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** 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.
*/
uint8_t CCID_GetSlotStatus(uint8_t slot,
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
* whenever an application at the host wants to send a block of bytes to the device
Endpoint_ClearIN();
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:
{
uint8_t Bwi = Endpoint_Read_8();
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)
{
var deviceVid = 0x03EB;
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_IccPowerOff = 0x63;
var CCID_PC_to_RDR_GetSlotStatus = 0x65;
-var CCID_PC_to_RDR_XfrBlock = 0x6f;
+var CCID_PC_to_RDR_XfrBlock = 0x6f;
function getAndInitCcidDeviceAndInterface()
{
//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)
{
return [
}
-function startTest()
+function testCcidMessages()
{
- async.series([
+ return [
function(callback) {
write(ccidInterface, new Buffer(IccPowerOnMessage(0, 1)), callback);
},
read(ccidInterface, 10, 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) {
- 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();
#define CCID_ICCSTATUS_NOICCPRESENT (1 << 1)
#define CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR 0
+ #define CCID_COMMANDSTATUS_ERROR 1
#define CCID_COMMANDSTATUS_FAILED (1 << 6)
#define CCID_COMMANDSTATUS_TIMEEXTENSIONREQUESTED (2 << 6)
#define CCID_COMMANDSTATUS_RFU (3 << 6)
#define CCID_ERROR_CMD_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_DESCRIPTOR_CLOCK_KHZ(khz) (khz)
Endpoint_ClearIN();
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();
} 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.
*/
+ USB_CCID_ProtocolData_T0_t ProtocolData;
} USB_ClassInfo_CCID_Device_t;
/* Function Prototypes: */
uint8_t slot,
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
* Send a block of bytes from the host to a slot in the device
* and also received a block of bytes as a response