hid_read not returning expected data (libusb) #556

Closed
opened 2023-05-17 05:47:39 -05:00 by VexedUXR · 4 comments
VexedUXR commented 2023-05-17 05:47:39 -05:00 (Migrated from github.com)

When using hid_read to receive data from the device (NZXT kraken x63) the expected value of the first two bytes is 0x11 (report id) and 0x01, however they arent always received. They are consistently received with the hidraw backend.

Explanation:
The NZXT kraken x63 periodically sends a device status packet with the report id of 0x75 and the first byte 0x02.
The command im sending it via hid_write consists of two bytes 0x10 (report id) and 0x01, this should make the device respond with a report id of 0x11 and the first byte 0x01, this dosent always happen, sometimes it takes a few reads (which makes sense, a few device status packets could be queued) but other times the response isnt received at all.
With the hidraw backend the response is always instantly received.

Program:

int main(int argc, char** argv)
{
    hid_device* dev = hid_open(0x1e71, 0x2007, NULL);

    unsigned char   buf[64] = {0};
    buf[0] = 0x10;
    buf[1] = 0x01;

    hid_write(dev, buf, 64);

    int ret_val;
    do
    {
        ret_val = hid_read(dev, buf, sizeof(buf));
        printf("read %d bytes. buf[0]=0x%x buf[1]=0x%x\n", ret_val, (int)buf[0], (int)buf[1]);
    } while( (ret_val != 64) || (buf[0] != 0x11) || (buf[1] != 0x01) );

    printf("Received response\n");
    hid_close(dev);
    hid_exit();

    return 0;
}

Example:

$ sudo ./backend_raw
read 64 bytes. buf[0]=0x11 buf[1]=0x1
Recived response

$ sudo ./backend_raw
read 64 bytes. buf[0]=0x11 buf[1]=0x1
Recived response

$ sudo ./backend_raw
read 64 bytes. buf[0]=0x11 buf[1]=0x1
Recived response

$ sudo ./backend_usb
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
...

$ sudo ./backend_usb
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x11 buf[1]=0x1
Recived response

$ sudo ./backend_usb
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
read 64 bytes. buf[0]=0x75 buf[1]=0x2
...

tested on linux and freebsd(libusb only) with hidapi v 13.1

Edit: formatting

When using hid_read to receive data from the device (NZXT kraken x63) the expected value of the first two bytes is `0x11` (report id) and `0x01`, however they arent always received. They are consistently received with the hidraw backend. Explanation: The NZXT kraken x63 periodically sends a device status packet with the report id of `0x75` and the first byte `0x02`. The command im sending it via hid_write consists of two bytes `0x10` (report id) and `0x01`, this should make the device respond with a report id of `0x11` and the first byte `0x01`, this dosent always happen, sometimes it takes a few reads (which makes sense, a few device status packets could be queued) but other times the response isnt received at all. With the hidraw backend the response is always instantly received. Program: ``` int main(int argc, char** argv) { hid_device* dev = hid_open(0x1e71, 0x2007, NULL); unsigned char buf[64] = {0}; buf[0] = 0x10; buf[1] = 0x01; hid_write(dev, buf, 64); int ret_val; do { ret_val = hid_read(dev, buf, sizeof(buf)); printf("read %d bytes. buf[0]=0x%x buf[1]=0x%x\n", ret_val, (int)buf[0], (int)buf[1]); } while( (ret_val != 64) || (buf[0] != 0x11) || (buf[1] != 0x01) ); printf("Received response\n"); hid_close(dev); hid_exit(); return 0; } ``` Example: ``` $ sudo ./backend_raw read 64 bytes. buf[0]=0x11 buf[1]=0x1 Recived response $ sudo ./backend_raw read 64 bytes. buf[0]=0x11 buf[1]=0x1 Recived response $ sudo ./backend_raw read 64 bytes. buf[0]=0x11 buf[1]=0x1 Recived response $ sudo ./backend_usb read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 ... $ sudo ./backend_usb read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x11 buf[1]=0x1 Recived response $ sudo ./backend_usb read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 read 64 bytes. buf[0]=0x75 buf[1]=0x2 ... ``` tested on linux and freebsd(libusb only) with hidapi v 13.1 Edit: formatting
Youw commented 2023-05-17 10:22:41 -05:00 (Migrated from github.com)

A duplicate of #274 (and a known limitation).

A duplicate of #274 (and a known limitation).
VexedUXR commented 2023-05-17 10:38:12 -05:00 (Migrated from github.com)

oh, would the only solution be to use hidraw?
my main goal was to use this on freebsd

oh, would the only solution be to use hidraw? my main goal was to use this on freebsd
Youw commented 2023-05-17 10:42:41 -05:00 (Migrated from github.com)
See: https://github.com/libusb/hidapi/issues/274#issuecomment-1542321797 And: https://github.com/libusb/hidapi/issues/274#issuecomment-1542947228
VexedUXR commented 2023-05-17 10:51:19 -05:00 (Migrated from github.com)

thanks :)

thanks :)
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-libusb/hidapi#556
No description provided.