hidapi
hidapi copied to clipboard
Properly determine libusb read size for large reports (Fixes #274)
Currently the libusb version of hidapi simply reads up to wMaxPacketSize bytes as the report. This is problematic when reports are longer than wMaxPacketSize. The current behavior will split that report up.
The proper solution is to review the report descriptor to find the longest input report and use that as the length of the libusb_fill_interrupt_transfer buffer. (Note: there is no need to manually get multiple USB packets and concatenate them together to fit the report length. USB already handles that for us.)
This will still work for HID devices when some input reports are shorter than others. The HID device will just send a short packet terminator and libusb will give us the shorter buffer.
The substance of these changes is in the get_max_input_size method. It uses the same basic report descriptor parsing as get_usage. I considered changing the code so that there could be shared parsing code, but I decided that was overkill for this.
Fixes #274
PR updated to remove different signedness comparison compiler warning when compiling with -Wall.
Thank you for finally taking care of this longstanding bug.
BTW, there is a typo here. @Youw and @JoergAtGithub. https://github.com/libusb/hidapi/blob/0ab6c14264ec76e9328a8eedb3b72b5d27dffd47/windows/test/data/046A_0011_0006_0001.pp_data#L4
dev->manufacturer_string = "dev->product_string = "dev->release_number = 0x0100
I put 046A_0011_0006_0001_real.rpt_desc into https://eleccelerator.com/usbdescreqparser/ and got:
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0xE0, // Usage Minimum (0xE0)
0x29, 0xE7, // Usage Maximum (0xE7)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0x00, // Usage Minimum (0x00)
0x29, 0xDD, // Usage Maximum (0xDD)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xDD, 0x00, // Logical Maximum (221)
0x75, 0x08, // Report Size (8)
0x95, 0x06, // Report Count (6)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x03, // Usage Maximum (Scroll Lock)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x03, // Report Count (3)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x75, 0x05, // Report Size (5)
0x95, 0x01, // Report Count (1)
0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
The InputReport contains:
- 8x1bit data
- 1x8bit constant padding
- 6x8bit data
This sums to 8byte, but
InputReportByteLengthis defined as follows: Specifies the maximum size, in bytes, of all the input reports. Includes the report ID, which is prepended to the report data. If report ID is not used, the ID value is zero. So we've to add a byte for the ReportID and are at 9 bytes.
BTW, there is a typo here. @Youw and @JoergAtGithub.
https://github.com/libusb/hidapi/blob/0ab6c14264ec76e9328a8eedb3b72b5d27dffd47/windows/test/data/046A_0011_0006_0001.pp_data#L4
dev->manufacturer_string = "dev->product_string = "dev->release_number = 0x0100
There is something missing, as this is autogenerated by pp_data_dump, I guess there was something in the manufacturer_string , that pp_data_dump couldn't handle. Could you please open a dedicated issue for this, as this is unrelated to this PR.
There is something missing, as this is autogenerated by pp_data_dump, I guess there was something in the manufacturer_string , that pp_data_dump couldn't handle. Could you please open a dedicated issue for this, as this is unrelated to this PR.
- https://github.com/libusb/hidapi/issues/729
Thanks @JoergAtGithub for walking me through that. I was misreading the descriptor.
I have added tests for libusb using the same data as the windows tests. And I extended the functionality of the libusb method to be able to calculate the maximum output and feature report sizes as well. This has no functional use currently, but it lets us run three times as many tests since the pp_data files have all three max sizes available.
And I extended the functionality of the libusb method to be able to calculate the maximum output and feature report sizes as well. This has no functional use currently, but it lets us run three times as many tests since the pp_data files have all three max sizes available.
Independent of this PR, I think it would generally make sense to store these 3 values in the device structure. On Windows we would have to use the values InputReportByteLength, OutputReportByteLength and FeatureReportByteLength from https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/hidpi/ns-hidpi-_hidp_caps . On all other backends we could use your parser to determine them - and with the testcase you proved that they are the same as on Windows.
In this way, we were able to programmatically determine the required buffer sizes for read/write operations on all platforms. @Youw What do you think about this?
And I extended the functionality of the libusb method to be able to calculate the maximum output and feature report sizes as well. This has no functional use currently, but it lets us run three times as many tests since the pp_data files have all three max sizes available.
Independent of this PR, I think it would generally make sense to store these 3 values in the device structure. On Windows we would have to use the values
InputReportByteLength,OutputReportByteLengthandFeatureReportByteLengthfrom https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/hidpi/ns-hidpi-_hidp_caps . On all other backends we could use your parser to determine them - and with the testcase you proved that they are the same as on Windows. In this way, we were able to programmatically determine the required buffer sizes for read/write operations on all platforms. @Youw What do you think about this?
Lets continue here: https://github.com/libusb/hidapi/issues/731
This PR does not seem to work.
Test device is the same as the one used in Issue #274. The FW is a mod of Jan Axelson's FX2HID example and codes are included in the following #274 comment.
- https://github.com/libusb/hidapi/issues/274#issuecomment-1547968118
I can reproduce the issue reported in #274 with hidapi git libusb backend, hidraw backend is okay.
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ sudo ./hidapitester_hidraw_git --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading 129-byte input report 0, 250 msec timeout...read 128 bytes:
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
00
Closing device
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ sudo ./hidapitester_libusb_git --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading 129-byte input report 0, 250 msec timeout...read 64 bytes:
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00
Closing device
With this PR, no change in hidraw backend behavior, which is good.
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ sudo ./hidapitester_hidraw_pr728 --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading 129-byte input report 0, 250 msec timeout...read 128 bytes:
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
00
Closing device
But the libusb backend fix is not working.
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ make -f Makefile_pr728.libusb
cc -I/usr/local/include/libusb-1.0 -I ../hidapi_pr728/hidapi -c ../hidapi_pr728/libusb/hid.c -o ../hidapi_pr728/libusb/hid.o
cc -I/usr/local/include/libusb-1.0 -I ../hidapi_pr728/hidapi -c hidapitester.c -o hidapitester.o
cc -I/usr/local/include/libusb-1.0 -I ../hidapi_pr728/hidapi ../hidapi_pr728/libusb/hid.o hidapitester.o -o hidapitester -L/usr/local/lib -lusb-1.0 -pthread
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ mv hidapitester hidapitester_libusb_pr728
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ sudo ./hidapitester_libusb_pr728 --vidpid 0925:1234 --open --buflen 256 -l 128 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 128-bytes...wrote 128 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
Reading 128-byte input report 0, 250 msec timeout...read 0 bytes:
Closing device
HID Report Descriptor.
ReportDscr:
db 06h, 0A0h, 0FFh ; Usage Page (FFA0h, vendor defined)
db 09h, 01h ; Usage (vendor defined)
db 0A1h, 01h ; Collection (Application)
db 09h, 02h ; Usage (vendor defined)
db 0A1h, 00h ; Collection (Physical)
db 06h, 0A1h, 0FFh ; Usage Page (vendor defined)
;; The Input report
db 09h, 03h ; Usage (vendor defined)
db 09h, 04h ; Usage (vendor defined)
db 15h, 80h ; Logical minimum (80h or -128)
db 25h, 7Fh ; Logical maximum (7Fh or 127)
db 35h, 00h ; Physical minimum (0)
db 45h, 0FFh ; Physical maximum (255)
db 75h, 08h ; Report size (8 bits)
db 95h, 80h ; Report count (128 fields)
db 81h, 02h ; Input (data, variable, absolute)
;; The Output report
db 09h, 05h ; Usage (vendor defined)
db 09h, 06h ; Usage (vendor defined)
db 15h, 80h ; Logical minimum (80h or -128)
db 25h, 7Fh ; Logical maximum (7Fh or 127)
db 35h, 00h ; Physical minimum (0)
db 45h, 0FFh ; Physical maximum (255)
db 75h, 08h ; Report size (8 bits)
db 95h, 80h ; Report count (128 fields)
db 91h, 02h ; Output (data, variable, absolute)
db 0C0h ; End Collection (Physical)
db 0C0h ; End Collection (Application)
ReportDscrEnd:
hidtest is okay.
mcuee@UbuntuSwift3 ~/build/hid/hidapi (master)$ sudo ./hidtest/hidtest-libusb
hidapi test/example tool. Compiled with hidapi version 0.15.0, runtime version 0.15.0.
Compile-time version matches runtime version of hidapi.
Device Found
type: 0925 1234
path: 3-2.1:1.0
serial_number: (null)
Manufacturer: CYPRESS
Product: EZ-USB FX2 HID USBHIDIO
Release: 0
Interface: 0
Usage (page): 0x0 (0x0)
Bus type: 1 (USB)
Report Descriptor: (52 bytes)
0x06, 0xa0, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x02, 0xa1,
0x00, 0x06, 0xa1, 0xff, 0x09, 0x03, 0x09, 0x04, 0x15, 0x80,
0x25, 0x7f, 0x35, 0x00, 0x45, 0xff, 0x75, 0x08, 0x95, 0x80,
0x81, 0x02, 0x09, 0x05, 0x09, 0x06, 0x15, 0x80, 0x25, 0x7f,
0x35, 0x00, 0x45, 0xff, 0x75, 0x08, 0x95, 0x80, 0x91, 0x02,
0xc0, 0xc0,
unable to open device
If I have time, I'll try to address @JoergAtGithub and @Youw's comments on Monday.
@mcuee I tried feeding the report descriptor that you sent into get_max_report_size and it returned 129, which seems correct. I'll try to look into this on Monday as well.
I did notice a typo in your test. When you ran ./hidapitester_libusb_pr728, you specified -l 128 which should have been -l 129, but I think it should have returned data anyway.
Let me try again.
mcuee@UbuntuSwift3 ~/build/cyusb/fxload_libusb (master)$ sudo ./fxload -v -t fx2lp -I ./fx2hid.hex -D /dev/bus/usb/003/019
microcontroller type: fx2lp
single stage: load on-chip memory
open RAM hexfile image ./fx2hid.hex
stop CPU
write on-chip, addr 0x0600 len 234 (0x00ea)
write on-chip, addr 0x09e5 len 10 (0x000a)
write on-chip, addr 0x0380 len 428 (0x01ac)
write on-chip, addr 0x0080 len 768 (0x0300)
write on-chip, addr 0x0033 len 3 (0x0003)
write on-chip, addr 0x09ff len 7 (0x0007)
write on-chip, addr 0x07b8 len 92 (0x005c)
write on-chip, addr 0x0851 len 59 (0x003b)
write on-chip, addr 0x05fe len 2 (0x0002)
write on-chip, addr 0x0a07 len 4 (0x0004)
write on-chip, addr 0x09ef len 8 (0x0008)
write on-chip, addr 0x09b0 len 18 (0x0012)
write on-chip, addr 0x09f7 len 8 (0x0008)
write on-chip, addr 0x09c2 len 18 (0x0012)
write on-chip, addr 0x0a0b len 6 (0x0006)
write on-chip, addr 0x091d len 40 (0x0028)
write on-chip, addr 0x096a len 24 (0x0018)
write on-chip, addr 0x06ea len 22 (0x0016)
write on-chip, addr 0x099a len 22 (0x0016)
write on-chip, addr 0x088c len 54 (0x0036)
write on-chip, addr 0x0982 len 24 (0x0018)
write on-chip, addr 0x0814 len 61 (0x003d)
write on-chip, addr 0x0a11 len 36 (0x0024)
write on-chip, addr 0x08f1 len 44 (0x002c)
write on-chip, addr 0x08c2 len 47 (0x002f)
write on-chip, addr 0x0945 len 20 (0x0014)
write on-chip, addr 0x05b8 len 70 (0x0046)
write on-chip, addr 0x0959 len 17 (0x0011)
write on-chip, addr 0x0043 len 3 (0x0003)
write on-chip, addr 0x0053 len 3 (0x0003)
write on-chip, addr 0x0700 len 184 (0x00b8)
write on-chip, addr 0x0000 len 3 (0x0003)
write on-chip, addr 0x052c len 12 (0x000c)
write on-chip, addr 0x09d4 len 17 (0x0011)
write on-chip, addr 0x0538 len 128 (0x0080)
write on-chip, addr 0x0a06 len 1 (0x0001)
... WROTE: 2497 bytes, 36 segments, avg 69
reset CPU
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ sudo ./hidapitester_libusb_pr728 --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading 129-byte input report 0, 250 msec timeout...read 0 bytes:
Closing device
mcuee@UbuntuSwift3 ~/build/hid/hidapitester (master)$ sudo ./hidapitester_hidraw_pr728 --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading 129-byte input report 0, 250 msec timeout...read 128 bytes:
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
00
Closing device
Same problem under FreeBSD 14.1 Release.
This is with a physical machine, Chuwi mini PC, Intel J4125 CPU, 8GB/256GB configuration.
Without this PR, hidapi git has the problem mentioned in #274.
But then somehow this PR does not work.
mcuee@freebsd14:~/build/hidapi_pr730 $ uname -a
FreeBSD freebsd14 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64
mcuee@freebsd14:~ $ sudo lsusb
Bus /dev/usb Device /dev/ugen0.5: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
Bus /dev/usb Device /dev/ugen0.6: ID 04d8:003f Microchip Technology, Inc.
Bus /dev/usb Device /dev/ugen0.4: ID 13d3:3503 IMC Networks
Bus /dev/usb Device /dev/ugen0.3: ID 1ea7:0064 SHARKOON Technologies GmbH 2.4GHz Wireless rechargeable vertical mouse [More&Better]
Bus /dev/usb Device /dev/ugen0.2: ID 04f2:0760 Chicony Electronics Co., Ltd Acer KU-0760 Keyboard
Bus /dev/usb Device /dev/ugen0.1: ID 0000:0000
mcuee@freebsd14:~/build/hidapi_pr730 $ fxload
no device specified!
usage: fxload [-vV] [-B backend] [-l] [-t type] [-D devpath]
[-I firmware_hexfile] [-s loader] [-c config_byte]
[-L link] [-m mode]
... [-D devpath] overrides DEVICE= in env
... device types: one of an21, fx, fx2, fx2lp, fx3
... at least one of -I, -L, -m is required
mcuee@freebsd14:~/build/hidapi_pr730 $ fxload -t fx2lp -I ./fx2hid.hex -D vid=0x04b4,pid=0x8613
mcuee@freebsd14:~/build/hidapi_pr730 $ lsusb
Bus /dev/usb Device /dev/ugen0.6: ID 04d8:003f Microchip Technology, Inc.
mcuee@freebsd14:~/build/hidapi_pr730 $ sudo chmod 666 /dev/ugen0.5
mcuee@freebsd14:~/build/hidapi_pr730 $ lsusb
Bus /dev/usb Device /dev/ugen0.5: ID 0925:1234 Lakeview Research
Bus /dev/usb Device /dev/ugen0.6: ID 04d8:003f Microchip Technology, Inc.
mcuee@freebsd14:~/build/hidapitester $ ./hidapitester_libusb_git --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading up to 129-byte input report, 250 msec timeout...read 64 bytes:
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00
Closing device
mcuee@freebsd14:~/build/hidapitester $ ./hidapitester_libusb_pr728 --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading up to 129-byte input report, 250 msec timeout...read 0 bytes:
Closing device
If I use the original fx2hid example (loop back of two bytes output report and input report), it seems to me this PR works fine. But that just means this PR has no regression. http://janaxelson.com/hidpage.htm http://janaxelson.com/files/fx2hid.zip
mcuee@freebsd14:~/build/hidapitester $ sudo ./hidapitester_libusb_pr728 --vidpid 0925:1234 --open --buflen 3 -l 3 --send-output 0,1,2 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
01 02 00
Closing device
mcuee@freebsd14:~/build/hidapitester $ sudo ./hidapitester_libusb_git --vidpid 0925:1234 --open --buflen 3 -l 3 --send-output 0,1,2 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
01 02 00
Closing device
Just want to make sure the FW works fine, here is the test under Windows (native Windows HID backend).
Original fx2hid FW.
C:\work\libusb\hidapitester [main ≡ +6 ~0 -0 !]> .\hidapitester.exe --vidpid 0925:1234 --open --buflen 3 -l 3 --send-output 0,1,2 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
01 02 00
Closing device
My mod fx2hid FW (128 bytes report).
C:\work\libusb\hidapitester [main ≡ +6 ~0 -0 !]> .\hidapitester.exe --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
00
Closing device
@Be-ing and @JoergAtGithub
Just wondering if you can carry out the test using your test device with long reports as well. Thanks.
@sudobash1
Just wondering which test device you are using. Thanks.
I am using two test devices, one is a simple EZ-USB FX2LP board which is pretty cheap from many places.
The other is a very old Microchip USB demo board (PIC18F87J50 PIM), not worth buying now.
There are also github action build failure.
Run make install
[ 12%] Building C object src/linux/CMakeFiles/hidapi_hidraw.dir/hid.c.o
[ 25%] Linking C shared library libhidapi-hidraw.so
[ 25%] Built target hidapi_hidraw
[ 37%] Building C object src/libusb/CMakeFiles/hidapi_libusb.dir/hid.c.o
/home/runner/work/hidapi/hidapi/hidapisrc/libusb/hid.c: In function ‘get_max_report_size’:
/home/runner/work/hidapi/hidapi/hidapisrc/libusb/hid.c:331:2[9](https://github.com/libusb/hidapi/actions/runs/14115441113/job/39887008870?pr=728#step:5:10): error: comparison of integer expressions of different signedness: ‘int’ and ‘enum report_descr_type’ [-Werror=sign-compare]
331 | if (key_cmd == report_type) { /* Input / Output / Feature */
| ^~
cc1: all warnings being treated as errors
make[2]: *** [src/libusb/CMakeFiles/hidapi_libusb.dir/build.make:79: src/libusb/CMakeFiles/hidapi_libusb.dir/hid.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:206: src/libusb/CMakeFiles/hidapi_libusb.dir/all] Error 2
make: *** [Makefile:[13](https://github.com/libusb/hidapi/actions/runs/14115441113/job/39887008870?pr=728#step:5:14)6: all] Error 2
Error: Process completed with exit code 2.
I lost track on this one a bit. Can someone remind where do we stand right now? Except for failing CI - are there active change requests/fixes?
I lost track on this one a bit. Can someone remind where do we stand right now? Except for failing CI - are there active change requests/fixes?
It just does not work based on my testing, tested under Linux and FreeBSD using hidapitester. I also tested under Windows (with a minor hack on the hidapitester Makefile and hidapi libusb backend).
@sudobash1
Just wondering what is the test device you are using. Thanks. Please share the test results as well. I'd like to see if I can use similar test env as yours.
Sorry for going dark on this.
Just wondering what is the test device you are using. Thanks. Please share the test results as well. I'd like to see if I can use similar test env as yours.
@mcuee I made these changes to support a Chameleon 20 braille display in USB HID mode. Long story short I needed it to work with an embedded Linux system that is stuck on the 4.x kernel which predates HIDIOCSINPUT. So I switched to the libusb backend and ran into the report size issue. I also tested the libusb changes on a Fedora 39 machine.
I am getting a EZ-USB FX2LP board, so if you point me towards the firmware, I can try out that device. (Much cheaper than the Chameleon :grin:)
For me this grew out of a project for my work (the Chameleon with embedded Linux). Things have gotten pretty hectic, but I'm putting a reminder on my calendar to review this again in June.
@sudobash1
FW binary and source codes are here.
- https://github.com/libusb/hidapi/issues/478#issuecomment-1547963784
It is a quick minor modification of Jan Axelson's FX2HID example from here. http://janaxelson.com/hidpage.htm http://janaxelson.com/files/fx2hid.zip
There may be a bit of challenge if you want to rebuild the source code as it may require a full version of Keil C51 compiler. I happen to have access to a pretty old version of Keil C51 compiler at work. I am not so sure about the efforts to port the code to use the free sdcc toolchain. It may be possible because of the nice sdcc based libraries.
- https://github.com/djmuhlestein/fx2lib
- https://github.com/whitequark/libfx2
Jan's HID page has some other FW as well, for example, for Microchip USB PIC18. I was able to use that as a base for my other HIDAPI testing but I have not figured out how to increase the HID report size above 64 bytes with that FW. I have the PIC18F87J50 USB PIM (free tool from Microchip many years ago).
More testing device discussions:
- https://github.com/libusb/hidapi/discussions/743
Update with the main git branch to trigger another CI run.
@aokblast
Would you please run your test device against this PR for hidspi libusb backend under your FreeBSD (as well as other OS you have access to)? Thanks.
@cederom and @dl8dtl
Since you two are the FreeBSD power user I know of, please help to check if you can give this PR a try.
FreeBSD HIDAPI is now based on libusb, so it is affected by the Issue #274.
- #274
#274 has an impact on avrdude as well.
@mcuee builds okay, could you please provide test steps, its a long thread :-P
@mcuee builds okay, could you please provide test steps, its a long thread :-P
Great.
Test steps: using the normal libusb backend of HIDAPI and this PR.
-
Test with your normal generic USB HID device using hidapi's built-in hidtest and hidapitester. This should be okay. https://github.com/todbot/hidapitester
-
Test with USB Full Speed HID device with >64 Bytes HID report size. This may fail.
-
Test with USB High Speed HID device with >64 Bytes HID report side. This may fail.
I have mentioned my test device in the comments above (EZ-USB FX2LP) but you can use other test device if you can.
- https://github.com/libusb/hidapi/pull/728#issuecomment-2899398658
@mcuee
FW binary and source codes are here.
Thanks. I finally got my EZ-USB FX2LP dev board from ebay. I've never worked with these before. How do I flash the hex file onto them? This is as far as I got:
stephen@taurus:~$ lsusb | grep FX2
Bus 001 Device 017: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
stephen@taurus:~$ sudo fxload -D /dev/bus/usb/001/017 -I fx2hid_128bytes/fx2hid.hex -v
microcontroller type: fx
single stage: load on-chip memory
open RAM hexfile image fx2hid_128bytes/fx2hid.hex
stop CPU
write on-chip, addr 0x0600 len 234 (0x00ea)
write on-chip, addr 0x09e5 len 10 (0x000a)
write on-chip, addr 0x0380 len 428 (0x01ac)
write on-chip, addr 0x0080 len 768 (0x0300)
write on-chip, addr 0x0033 len 3 (0x0003)
write on-chip, addr 0x09ff len 7 (0x0007)
write on-chip, addr 0x07b8 len 92 (0x005c)
write on-chip, addr 0x0851 len 59 (0x003b)
write on-chip, addr 0x05fe len 2 (0x0002)
write on-chip, addr 0x0a07 len 4 (0x0004)
write on-chip, addr 0x09ef len 8 (0x0008)
write on-chip, addr 0x09b0 len 18 (0x0012)
write on-chip, addr 0x09f7 len 8 (0x0008)
write on-chip, addr 0x09c2 len 18 (0x0012)
write on-chip, addr 0x0a0b len 6 (0x0006)
write on-chip, addr 0x091d len 40 (0x0028)
write on-chip, addr 0x096a len 24 (0x0018)
write on-chip, addr 0x06ea len 22 (0x0016)
write on-chip, addr 0x099a len 22 (0x0016)
write on-chip, addr 0x088c len 54 (0x0036)
write on-chip, addr 0x0982 len 24 (0x0018)
write on-chip, addr 0x0814 len 61 (0x003d)
write on-chip, addr 0x0a11 len 36 (0x0024)
write on-chip, addr 0x08f1 len 44 (0x002c)
write on-chip, addr 0x08c2 len 47 (0x002f)
write on-chip, addr 0x0945 len 20 (0x0014)
write on-chip, addr 0x05b8 len 70 (0x0046)
write on-chip, addr 0x0959 len 17 (0x0011)
write on-chip, addr 0x0043 len 3 (0x0003)
write on-chip, addr 0x0053 len 3 (0x0003)
write on-chip, addr 0x0700 len 184 (0x00b8)
write on-chip, addr 0x0000 len 3 (0x0003)
write on-chip, addr 0x052c len 12 (0x000c)
write on-chip, addr 0x09d4 len 17 (0x0011)
write on-chip, addr 0x0538 len 128 (0x0080)
write on-chip, addr 0x0a06 len 1 (0x0001)
... WROTE: 2497 bytes, 36 segments, avg 69
reset CPU
No errors, but nothing seems to happen. No hid device shows up & there is no USB re-enumeration. (Fedora 42, Linux kernel 6.14.11)