diff options
| author | Filipe Rodrigues <filipepazrodrigues@gmail.com> | 2018-06-17 17:51:09 -0700 | 
|---|---|---|
| committer | Filipe Rodrigues <filipepazrodrigues@gmail.com> | 2018-06-24 19:02:31 -0700 | 
| commit | 1e9e7bc8b88af32f466f7438a06fb8dc96b3035d (patch) | |
| tree | e98406a2fbe9a10df2f186adcac27ab1a9d02568 /Demos/Device | |
| parent | bc57f4ea5afd29f2e0f0175d14cf1540b4408de8 (diff) | |
| download | lufa-1e9e7bc8b88af32f466f7438a06fb8dc96b3035d.tar.gz lufa-1e9e7bc8b88af32f466f7438a06fb8dc96b3035d.tar.bz2 lufa-1e9e7bc8b88af32f466f7438a06fb8dc96b3035d.zip | |
CCID: Add support for PC-to-Reader XfrBlock message
Diffstat (limited to 'Demos/Device')
| -rw-r--r-- | Demos/Device/ClassDriver/CCID/CCID.c | 28 | ||||
| -rw-r--r-- | Demos/Device/ClassDriver/CCID/CCID.h | 7 | ||||
| -rw-r--r-- | Demos/Device/ClassDriver/CCID/Descriptors.c | 4 | ||||
| -rw-r--r-- | Demos/Device/ClassDriver/CCID/Descriptors.h | 2 | ||||
| -rw-r--r-- | Demos/Device/LowLevel/CCID/CCID.c | 89 | ||||
| -rw-r--r-- | Demos/Device/LowLevel/CCID/Descriptors.c | 4 | ||||
| -rw-r--r-- | Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js | 15 | 
7 files changed, 132 insertions, 17 deletions
| diff --git a/Demos/Device/ClassDriver/CCID/CCID.c b/Demos/Device/ClassDriver/CCID/CCID.c index 9059ad40d..bb4c11c45 100644 --- a/Demos/Device/ClassDriver/CCID/CCID.c +++ b/Demos/Device/ClassDriver/CCID/CCID.c @@ -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 slot,  							uint8_t seq, diff --git a/Demos/Device/ClassDriver/CCID/CCID.h b/Demos/Device/ClassDriver/CCID/CCID.h index f6dd4adf5..88c29aef1 100644 --- a/Demos/Device/ClassDriver/CCID/CCID.h +++ b/Demos/Device/ClassDriver/CCID/CCID.h @@ -86,6 +86,13 @@  		uint8_t CALLBACK_CCID_GetSlotStatus(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo,  		                                    uint8_t slot,  		                                    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 slot,  		                            uint8_t seq, diff --git a/Demos/Device/ClassDriver/CCID/Descriptors.c b/Demos/Device/ClassDriver/CCID/Descriptors.c index 43a696194..886042668 100644 --- a/Demos/Device/ClassDriver/CCID/Descriptors.c +++ b/Demos/Device/ClassDriver/CCID/Descriptors.c @@ -117,8 +117,8 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =  			.MaxIFSD				= 2038,  			.SynchProtocols			= 0,  			.Mechanical				= 0, -			.Features				= 0x0400fe, -			.MaxCCIDMessageLength	= 0x0c00, +			.Features				= CCID_Features_ExchangeLevel_ShortAPDU | CCID_Features_Auto_ParameterConfiguration| CCID_Features_Auto_ICCActivation | CCID_Features_Auto_VoltageSelection, +			.MaxCCIDMessageLength	= CCID_EPSIZE,  			.ClassGetResponse		= 0xff,  			.ClassEnvelope			= 0xff,  			.LcdLayout				= 0, diff --git a/Demos/Device/ClassDriver/CCID/Descriptors.h b/Demos/Device/ClassDriver/CCID/Descriptors.h index 239d612ab..63672d1b7 100644 --- a/Demos/Device/ClassDriver/CCID/Descriptors.h +++ b/Demos/Device/ClassDriver/CCID/Descriptors.h @@ -49,7 +49,7 @@  		/** Endpoint address of the CCID data OUT endpoint, for host-to-device data transfers. */  		#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 diff --git a/Demos/Device/LowLevel/CCID/CCID.c b/Demos/Device/LowLevel/CCID/CCID.c index 764392de0..24849dc12 100644 --- a/Demos/Device/LowLevel/CCID/CCID.c +++ b/Demos/Device/LowLevel/CCID/CCID.c @@ -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   *  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. @@ -293,7 +320,8 @@ void CCID_Task(void)  {  	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;  	AbortedSeq = -1; @@ -313,7 +341,7 @@ void CCID_Task(void)  			case CCID_PC_to_RDR_IccPowerOn:  			{  				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.Slot        = CCIDHeader.Slot; @@ -350,7 +378,7 @@ void CCID_Task(void)  			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.Length      = 0;  				ResponsePowerOff->CCIDHeader.Slot        = CCIDHeader.Slot; @@ -373,7 +401,7 @@ void CCID_Task(void)  			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.Length      = 0;  				ResponseSlotStatus->CCIDHeader.Slot        = CCIDHeader.Slot; @@ -394,9 +422,56 @@ void CCID_Task(void)  				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:  			{ -				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.Length      = 0;  				ResponseAbort->CCIDHeader.Slot        = CCIDHeader.Slot; @@ -418,10 +493,10 @@ void CCID_Task(void)  			}  			default:  			{ -				memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); +				memset(ResponseBuffer, 0x00, sizeof(ResponseBuffer));  				Endpoint_SelectEndpoint(CCID_IN_EPADDR); -				Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); +				Endpoint_Write_Stream_LE(ResponseBuffer, sizeof(ResponseBuffer), NULL);  				Endpoint_ClearIN();  			}  		} diff --git a/Demos/Device/LowLevel/CCID/Descriptors.c b/Demos/Device/LowLevel/CCID/Descriptors.c index c82216c9b..5e092e2e4 100644 --- a/Demos/Device/LowLevel/CCID/Descriptors.c +++ b/Demos/Device/LowLevel/CCID/Descriptors.c @@ -119,8 +119,8 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =  			.MaxIFSD				= 2038,  			.SynchProtocols			= 0,  			.Mechanical				= 0, -			.Features				= 0x0400fe, -			.MaxCCIDMessageLength	= 0x0c00, +			.Features				= CCID_Features_ExchangeLevel_ShortAPDU | CCID_Features_Auto_ParameterConfiguration| CCID_Features_Auto_ICCActivation | CCID_Features_Auto_VoltageSelection, +			.MaxCCIDMessageLength	= CCID_EPSIZE,  			.ClassGetResponse		= 0xff,  			.ClassEnvelope			= 0xff,  			.LcdLayout				= 0, 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 993c0e550..e521cdb5a 100644 --- a/Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js +++ b/Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js @@ -106,17 +106,16 @@ function GetSlotStatusMessage(slot, seq)      ];  } -function XfrBlockMessage(slot, seq) +function XfrBlockMessage(slot, seq, apdu)  {      return [          CCID_PC_to_RDR_XfrBlock, //message type -        5, 0, 0, 0, //length (05) +        apdu.length, 0, 0, 0, //length: only for < 0xFF          slot,          seq,          0, //BWI  -        0, 0, //level parameter -        0, 0xfd, 0, 0, 0 //message -    ]; +        0, 0 //level parameter +    ].concat(apdu);  } @@ -140,6 +139,12 @@ function startTest()          },          function(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);          }          ]);  } | 
