Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Erik Strand
lufa
Commits
f1b06c5b
Unverified
Commit
f1b06c5b
authored
Aug 06, 2018
by
Dean Camera
Committed by
GitHub
Aug 06, 2018
Browse files
Merge pull request #135 from kidbomb/feature-ccid-get-set-parameters
CCID: Support for Get and Set Parameters
parents
941bc147
a877ffb6
Changes
6
Show whitespace changes
Inline
Side-by-side
Demos/Device/ClassDriver/CCID/CCID.c
View file @
f1b06c5b
...
...
@@ -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. T
H
is message is sent to the device
/** Event handler for the CCID_PC_to_RDR_GetSlotStatus. T
h
is 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
...
...
Demos/Device/LowLevel/CCID/CCID.c
View file @
f1b06c5b
...
...
@@ -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
)
{
...
...
Demos/Device/LowLevel/CCID/HostTestApp/test_generic_ccid_libusb.js
View file @
f1b06c5b
...
...
@@ -23,6 +23,8 @@ 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
;
...
...
@@ -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
startT
es
t
()
function
testCcidMessag
es
()
{
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
(
XfrBlock
Message
(
0
,
4
,
[
0x
0
,
0x
FD
,
0x0
,
0x0
,
0x0
])),
callback
);
write
(
ccidInterface
,
new
Buffer
(
SetParameters
Message
(
0
,
4
,
0
,
[
0x
11
,
0x
00
,
0x0
0
,
0x0
a
,
0x0
0
])),
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
();
...
...
LUFA/Drivers/USB/Class/Common/CCIDClassCommon.h
View file @
f1b06c5b
...
...
@@ -81,6 +81,7 @@
#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)
...
...
@@ -91,6 +92,8 @@
#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)
...
...
LUFA/Drivers/USB/Class/Device/CCIDClassDevice.c
View file @
f1b06c5b
...
...
@@ -231,7 +231,76 @@ void CCID_Device_USBTask(USB_ClassInfo_CCID_Device_t* const CCIDInterfaceInfo)
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
();
...
...
LUFA/Drivers/USB/Class/Device/CCIDClassDevice.h
View file @
f1b06c5b
...
...
@@ -84,6 +84,7 @@
}
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: */
...
...
@@ -155,6 +156,38 @@
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
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment