scratchfoundation / scratchx

Scratch Extension Site
https://github.com/llk/scratchx
190 stars 120 forks source link

Scratch Extension Plugin Cannot Connect To Devices With More Than One HID Interface #26

Closed CreativeComputerLab closed 1 year ago

CreativeComputerLab commented 9 years ago

The MakeSense device (http://makesense.co) exposes 3 HID interfaces and the Scratch plugin cannot seem to connect to any of them. The interfaces are: \?\hid#vid_04d8&pid_f46a&mi_00#7&e3da3d9&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} - 0 \?\hid#vid_04d8&pid_f46a&mi_01#7&3214e19b&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} - 0 \?\hid#vid_04d8&pid_f46a&mi_02#7&32de4c95&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} - 0

The device is known to work fine when connected to other SW via standard HID APIs.

khanning commented 9 years ago

I can confirm this issue on OSX 10.9.5.

The interface number can be accessed in _deviceConnected via:

ext._deviceConnected = function(dev) {
  if (dev.info["interface_number"] == 2) {
    // Connect
  }
};

However, even with the correct interface # the device fails to connect reliably.

When a read() is attempted on the device, most of the time, I'm getting one of the following results:

Result 1

  1. null is returned by read()
  2. _deviceRemoved is called
  3. attempt to reconnect the device via _deviceConnected
  4. null is returned by read()
  5. _deviceRemoved is called
  6. ...

Result 2

  1. TypeError: e is not a functionis printed in the console when read() is called
  2. _device Removed in NOT called
andrew-littlebits commented 9 years ago

I can confirm this issue on a different device on a Windows 7 Ultimate host.

I am using a compound device that enumerates as both CDC and RAWHID (but i'd like to talk over HID), and the HID interface is the 2nd interface on the device like above.

I can write to the device successfully, but reads always return a length 0 ByteArray. Reading through the extension source it looks like 0 length reads automatically disconnect the device (https://github.com/LLK/scratchx/blob/gh-pages/scratch_extensions/scratch_ext.js#L284). I am able to reproduce Result 1 above. However I can also confirm that data is being read by the USB Host to the INTERRUPT IN endpoint associated with the interface (endpoint 4).

I've also tried communicating directly with the device by making my own call to ScratchDeviceHost.hid_open() to retrieve a HidDevice object. Calls to write() function as expected, but when opened with nonblocking set to false, the callback supplied to read() or read_raw() is never executed. This avoids the toggling behavior of Result 1 above, but still fails to read data.

Is ScratchDeviceHost attempting to read from the associated INTERRUPT IN endpoint when read() is called? Any chance that the ScratchDeviceHost is selecting the wrong endpoint number?