Search code examples
c++windowsubuntuhidhidapi

Cannot read from HID device after migrating from fileapi.h ReadFile in windows to hidapi hid_read in Ubuntu


I have a library for communicating with a HID device. The library works fine under windows using fileapi.h and read/write with ReadFile and WriteFile. I now want to make this library platform independent so I decided to migrate to hidapi. On Ubuntu writing to the device with hid_write works fine, but I seem to struggle with hid_read_timeout. The read works, but the values I receive are not correct, i.e not the same as in Windows using fileapi.h.

I want to read some bytes into my data buffer

std::shared_ptr<unsigned char[]> data_buffer(new unsigned char[65]);

using

this->device_handle = hid_open(vid, pid, NULL);
hid_read_timeout(this->device_handle, data_buffer.get(), 65, 5000);

the read succeeds and the data consists of an array of ints so i later pairwise combine the bytes into ints

unsigned char high_byte = data_buffer[i];
unsigned char low_byte = data_buffer[i + 1];
uint16_t t = ((uint16_t)high_byte << 8) | low_byte;

This works fine in windows, and i cant figure out what i'm doing wrong. My knowledge about USB and HID protocols are very limited.

For reference in Windows i use

this->device_handle = CreateFile(device_path, GENERIC_READ,  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

To create a read file handle and the read looks something like

if (!ReadFile(this->device_handle, (LPVOID)data_buffer.get(), 65, &num_bytes_read, &overlapped)){
  switch (WaitForSingleObject(read_done_handle, 3000)){
    case WAIT_OBJECT_0:
      GetOverlappedResult(read_handle, &overlapped, &num_bytes_read, false);
      break;
    ...
  }
}

Any help/tips are appreciated!

I tried switching backen from libusb to hidraw but that did not make a difference. I also tried many other different things but my knowledge is limited when it comes to HID and USB communication.


Solution

  • The problem was that on Ubuntu using hidapi the array of bytes received from the firmware was shifted as when compared to Windows. On Windows I got an extra byte in the beginning of the received array!