From a877ffb6265ea3a18f1c95f61fdddc8b57c518cc Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Sun, 8 Jul 2018 20:18:27 -0700 Subject: CCID: Initial support for GetParameters and SetParameters --- Demos/Device/ClassDriver/CCID/CCID.c | 54 ++++++++- Demos/Device/LowLevel/CCID/CCID.c | 129 ++++++++++++++++++++- .../CCID/HostTestApp/test_generic_ccid_libusb.js | 54 +++++++-- 3 files changed, 227 insertions(+), 10 deletions(-) (limited to 'Demos') diff --git a/Demos/Device/ClassDriver/CCID/CCID.c b/Demos/Device/ClassDriver/CCID/CCID.c index bb4c11c45..15d2852e4 100644 --- a/Demos/Device/ClassDriver/CCID/CCID.c +++ b/Demos/Device/ClassDriver/CCID/CCID.c @@ -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 * */ @@ -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 * 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 diff --git a/Demos/Device/LowLevel/CCID/CCID.c b/Demos/Device/LowLevel/CCID/CCID.c index 24849dc12..e55651373 100644 --- a/Demos/Device/LowLevel/CCID/CCID.c +++ b/Demos/Device/LowLevel/CCID/CCID.c @@ -52,6 +52,8 @@ 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 @@ -59,6 +61,12 @@ static uint8_t AbortedSeq; */ int main(void) { + ProtocolData.FindexDindex = 0x11; + ProtocolData.TCCKST0 = 0x00; + ProtocolData.GuardTimeT0 = 0x00; + ProtocolData.WaitingIntegerT0 = 0x0A; + ProtocolData.ClockStop = 0x00; + SetupHardware(); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); @@ -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 - * 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, @@ -251,6 +259,54 @@ 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 @@ -421,7 +477,76 @@ void CCID_Task(void) 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(); @@ -441,7 +566,7 @@ void CCID_Task(void) 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) { diff --git a/Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js b/Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js index e521cdb5a..69cd1c28d 100644 --- a/Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js +++ b/Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js @@ -23,10 +23,12 @@ var sprintf = require('sprintf'); 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() { @@ -72,6 +74,30 @@ function write(ccidInterface, message, callback) //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 [ @@ -119,9 +145,9 @@ function XfrBlockMessage(slot, seq, apdu) } -function startTest() +function testCcidMessages() { - async.series([ + return [ function(callback) { write(ccidInterface, new Buffer(IccPowerOnMessage(0, 1)), callback); }, @@ -141,12 +167,26 @@ function startTest() 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(); -- cgit v1.2.3