1

I have been working on an website that uses WebUSB. The WebUSB library works 100% on Linux and Android. Unfortunately on Windows the promise returned by .claimInterface never returns anything, ever. And when I, for interest sake, run the claimInterface again the returned promise returns the error "An operation that changes state is in progress", confirming that the first claimInterface function is still busy.

The problem only occurs when claiming interface 1, claiming interface 0 works, but this interface is of no use to me. The USB device is not standard (descriptor dieplayed below) so it might be something about the device configuration, but it is really hard to tell with the lack of logs.

I did try and look at chrome://device-log?refresh=1 for additional logs, but only the plug events are dislpayed. I also enabled the new USB backend at chrome://flags/#new-usb-backend to no avail. I also tried running chrome with the --enable-loging --v1, but the only error that seemed relevant is: ERROR:device_event_log_impl.cc(211)] [01:32:33.170] USB: usb_device_handle_win.cc:1020 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F) .

But this error is logged before I have even connected a device, also discussed here, so I do not even know if it is relevant.

Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            2 Communications
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0xXXXX XXX
  idProduct          0xXXXX 
  bcdDevice            1.01
  iManufacturer           1 XXX
  iProduct                2 XXX
  iSerial                 3 XXX
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0030
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x40
      (Missing must-be-set bit!)
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 
      bInterfaceProtocol      1 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              32
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 
      bInterfaceProtocol      1 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              32
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              32
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0001
  Self Powered

The driver installation is almost identical to the WinUSB predescribed method.

[Version]
DriverVer=XX/XX/XXXX,X.X.X.X
Signature = "$Windows NT$"
Class = USBDevice
ClassGuid = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider = %ManufacturerName%
CatalogFile = XXX.cat

[ClassInstall32]
AddReg = ClassInstall_AddReg

[ClassInstall_AddReg]
HKR,,,,%ClassName%
HKR,,NoInstallClass,,1
HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20"
HKR,,LowerLogoVersion,,5.2

[WinUSBDeviceClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-20

[Manufacturer]
%ManufacturerName% = Standard,NTx86,NTamd64

[Standard.NTx86]
%DeviceName% = USB_Install, USB\%VendorID%&%ProductID%

[Standard.NTamd64]
%DeviceName% = USB_Install, USB\%VendorID%&%ProductID%

[USB_Install]
Include=winusb.inf
Needs=WINUSB.NT

[USB_Install.Services]
Include=winusb.inf
Needs=WINUSB.NT.Services

[USB_Install.HW]
AddReg=Dev_AddReg

[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}

[Strings]
ManufacturerName = "XXX"
ClassName="Universal Serial Bus devices"
DeviceName = "XXX"
VendorID = "VID_XXX"
ProductID = "PID_XXX"

As well as a React App I used to test the library.

import { useEffect, useState } from 'react';

export default function App() {
  const [devices, setDevices] = useState([]);

  useEffect(function () {
    update()
    navigator.usb.addEventListener("connect", update);
    navigator.usb.addEventListener("disconnect", update);
  }, [])

  return (
    <div className="App">
      <button onClick={refresh}>
        <div>Refresh</div>
      </button>
      <button onClick={connect}>
        <div>Connect</div>
      </button>
    </div>
  );


  function connect() {
    let _device = devices[0]
    if (_device) {
      _device
      .open()
      .then(function () {
        _device
          .selectConfiguration(1)
          .then(function () {
            console.log("Connecting to interface")
            _device
              .claimInterface(1)
              .then(function () {
                console.log("Success");
              })
              .catch(console.error);
          })
          .catch(console.error);
      })
      .catch(console.error);
    } 
  }

  function update() {
    navigator.usb.getDevices().then(function (_devices) {
      setDevices(_devices)
    });
  }
  
  function refresh() {
    navigator.usb
      ?.requestDevice({
        filters: [{ vendorId: 0xXXXX, productId: 0xXXXX }],
      })
      .then(update)
      .catch(console.error);
  }
}
Ruan
  • 21
  • 4

1 Answers1

1

I downloaded goole-chrome canary 89.0.4387.0 and it solved the problem. So I guess that is just google, solving the problem before I even asked the question.

Ruan
  • 21
  • 4