/* package */ HidDevice(String path, Frontend frontend) throws IOException { m_Frontend = frontend; udev udev = udev_new(); udev_device raw_dev = udev_device_new_from_syspath(udev, path); String dev_path = udev_device_get_devnode(raw_dev); udev_unref(udev); m_HidDeviceInfo = new HidDeviceInfo(path); // OPEN HERE // m_DeviceHandle = open(dev_path, O_RDWR); // If we have a good handle, return it. if (m_DeviceHandle <= 0) throw new IOException("open() failed, errno " + Native.getLastError()); // Get the report descriptor int[] desc_size = {0}; int res; hidraw_report_descriptor rpt_desc = new hidraw_report_descriptor(); // Get Report Descriptor Size res = ioctl(m_DeviceHandle, HIDIOCGRDESCSIZE, desc_size); if (res < 0) // FIXME ERROR HANDLING throw new IOException("ioctl(...HIDIOCGRDESCSIZE..) failed"); // perror("HIDIOCGRDESCSIZE"); // Get Report Descriptor rpt_desc.size = desc_size[0]; res = ioctl(m_DeviceHandle, HIDIOCGRDESC, rpt_desc); if (res < 0) throw new IOException("ioctl(...HIDIOCGRDESC..) failed"); // Determine if this device uses numbered reports. m_UsesNumberedReports = uses_numbered_reports(rpt_desc.value, rpt_desc.size); // --------------- // Magic here, assume that no HID device ever uses reports longer than 4kB m_InputReportBytes = new byte[4096 + 1]; m_OutputReportBytes = new byte[4096 + 1]; m_SyncStart = new SyncPoint(2); m_SyncShutdown = new SyncPoint(2); m_Thread = new Thread( new Runnable() { @Override public void run() { try { runReadOnBackground(); } catch (Exception e) { e.printStackTrace(); } } }, m_HidDeviceInfo.getPath()); m_Thread.start(); m_SyncStart.waitAndSync(); }
@Override public synchronized void close() { if (!m_Open) throw new IllegalStateException("device not open"); m_StopThread = true; UdevLibrary.close(m_DeviceHandle); m_Thread.interrupt(); m_SyncShutdown.waitAndSync(); m_Frontend.closeDevice(this); m_Open = false; }