private void runReadOnBackground() { m_SyncStart.waitAndSync(); while (!m_StopThread) { // In Linux read() from a HID device we always try to read at least as many bytes as there can // be in a report // the kernel will return with the actual number of bytes in the report (plus one if numbered // reports are used) // and the data will be preceded with the report number if and only if numbered reports are // used, which is // kind of stupid because then we need to know this and to know that it is necessary to (be // able to!) read // the HID descriptor AND parse it. I like the Mac OS and Windows ways better, what a mess the // world is! int bytes_read = read(m_DeviceHandle, m_InputReportBytes, m_InputReportBytes.length); if (m_InputReportListener != null) { byte reportID = 0; if (m_UsesNumberedReports) { reportID = m_InputReportBytes[0]; bytes_read--; System.arraycopy(m_InputReportBytes, 1, m_InputReportBytes, 0, bytes_read); } m_InputReportListener.onInputReport(this, reportID, m_InputReportBytes, bytes_read); } } m_SyncShutdown.waitAndSync(); }
@Override public synchronized int setOutputReport(byte reportID, byte[] data, int length) { if (!m_Open) throw new IllegalStateException("device not open"); // In Linux write() to HID device data is preceded with the report number only if numbered // reports are used // // "The first byte of the buffer passed to write() should be set to the report // number. If the device does not use numbered reports, the first byte should // be set to 0. The report data itself should begin at the second byte." // // References: // - https://www.kernel.org/doc/Documentation/hid/hidraw.txt // - http://www.usb.org/developers/hidpage/HID1_11.pdf if (m_UsesNumberedReports) m_OutputReportBytes[0] = reportID; else m_OutputReportBytes[0] = 0; System.arraycopy(data, 0, m_OutputReportBytes, 1, length); int len = write(m_DeviceHandle, m_OutputReportBytes, length + 1); if (len < 0) return len; return len - 1; }