Use a fixed size packet for sending

The Windows HID api always expects to receive a fixed size buffer
(corresponding to the largest report supported by the device). But
unlike the hidapi library, the libusb library doesn't automatically pad
the buffer to the expected size when trying to send less bytes. Thus
when trying to submit the transfer, the underlying Windows api call
immediately fails with ERROR_INVALID_PARAMETER.

To workaround this problem, pad the data packet with zeros manually and
always send the entire packet (1 byte report ID and 32 bytes payload).
This commit is contained in:
Jef Driesen 2017-09-22 21:50:28 +02:00
parent a28d2feb4f
commit ddb7276bf0

View File

@ -32,7 +32,8 @@
#define ISINSTANCE(device) dc_device_isinstance((device), &uwatec_g2_device_vtable)
#define PACKET_SIZE 64
#define RX_PACKET_SIZE 64
#define TX_PACKET_SIZE 32
typedef struct uwatec_g2_device_t {
dc_device_t base;
@ -66,7 +67,7 @@ static dc_status_t
receive_data (uwatec_g2_device_t *device, dc_event_progress_t *progress, unsigned char *data, unsigned int size)
{
while (size) {
unsigned char buf[PACKET_SIZE];
unsigned char buf[RX_PACKET_SIZE];
size_t transferred = 0;
dc_status_t rc = DC_STATUS_SUCCESS;
unsigned int len = 0;
@ -108,7 +109,7 @@ receive_data (uwatec_g2_device_t *device, dc_event_progress_t *progress, unsigne
static dc_status_t
uwatec_g2_transfer (uwatec_g2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
{
unsigned char buf[PACKET_SIZE];
unsigned char buf[TX_PACKET_SIZE + 1];
dc_status_t status = DC_STATUS_SUCCESS;
size_t transferred = 0;
@ -122,7 +123,8 @@ uwatec_g2_transfer (uwatec_g2_device_t *device, const unsigned char command[], u
buf[0] = 0;
buf[1] = csize;
memcpy(buf + 2, command, csize);
status = dc_usbhid_write (device->usbhid, buf, csize + 2, &transferred);
memset(buf + 2 + csize, 0, sizeof(buf) - (csize + 2));
status = dc_usbhid_write (device->usbhid, buf, sizeof(buf), &transferred);
if (status != DC_STATUS_SUCCESS) {
ERROR (device->base.context, "Failed to send the command.");
return status;