WebUSB - "Unable to claim interface" 错误
WebUSB - "Unable to claim interface" error
我正在尝试使用下面的代码通过 WebUSB API 使用 POS 打印机,但它在 .claimInterface()
失败,错误为 DOMException: Unable to claim interface
。所有测试均在 Linux 上的 Chrome 80.0.3987.116 上完成。我该如何调试?
(update) 我找到了 this demo 但它导致了同样的错误。
async function start () {
const device = await navigator.usb.requestDevice({
filters: [{
vendorId: 0x04b8,
productId: 0x0202
}]
});
await device.open();
await device.selectConfiguration(device.configurations[0].configurationValue);
await device.claimInterface(device.configurations[0].interfaces[0].interfaceNumber);
}
当然,我 运行 它在本地主机服务器上(即 "secure context")并使用用户手势调用 start()
函数。
我还确认没有其他进程正在使用该设备。
% lsof /dev/bus/usb/001/011
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
chrome 4156 ikr7 393u CHR 189,10 0t0 331233 /dev/bus/usb/001/011
下面是 lsusb -vs 001:011
.
的输出
Bus 001 Device 011: ID 04b8:0202 Seiko Epson Corp. Receipt Printer M129C/TM-T70
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x04b8 Seiko Epson Corp.
idProduct 0x0202 Receipt Printer M129C/TM-T70
bcdDevice 2.00
iManufacturer 1 EPSON
iProduct 2 EPSON UB-U01III
iSerial 3 20110125210031250M02C
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0020
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 2
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 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 0
Device Status: 0x0001
Self Powered
问题出在 usblp
由 Linux 内核自动加载的驱动程序。将其添加到黑名单解决了问题。这是我的 /etc/modprobe.d/blacklistusblp.conf
文件。
blacklist usblp
请注意,黑名单 usblp
会禁用所有使用 usblp
驱动程序的 USB 打印机,但幸运的是,包括我在内的大多数人都使用 CUPS 作为打印机驱动程序。
(update) 发现编写一个自动分离内核默认驱动程序而不是黑名单的 udev 规则会更好。这是我的 /etc/udev/rules.d/99-escpos.rules
.
SUBSYSTEM=="usb", ATTRS{idVendor}=="04b8", ATTRS{idProduct}=="0202", MODE="0664", GROUP="wheel", RUN+="/bin/sh -c 'echo -n $id:1.0 > /sys/bus/usb/drivers/usblp/unbind && echo -n $id:1.0 > /sys/bus/usb/drivers/usbfs/unbind'"
此规则还会卸载 usbfs
,当 usblp
分离时,内核偶尔会加载它。
我正在尝试使用下面的代码通过 WebUSB API 使用 POS 打印机,但它在 .claimInterface()
失败,错误为 DOMException: Unable to claim interface
。所有测试均在 Linux 上的 Chrome 80.0.3987.116 上完成。我该如何调试?
(update) 我找到了 this demo 但它导致了同样的错误。
async function start () {
const device = await navigator.usb.requestDevice({
filters: [{
vendorId: 0x04b8,
productId: 0x0202
}]
});
await device.open();
await device.selectConfiguration(device.configurations[0].configurationValue);
await device.claimInterface(device.configurations[0].interfaces[0].interfaceNumber);
}
当然,我 运行 它在本地主机服务器上(即 "secure context")并使用用户手势调用 start()
函数。
我还确认没有其他进程正在使用该设备。
% lsof /dev/bus/usb/001/011
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
chrome 4156 ikr7 393u CHR 189,10 0t0 331233 /dev/bus/usb/001/011
下面是 lsusb -vs 001:011
.
Bus 001 Device 011: ID 04b8:0202 Seiko Epson Corp. Receipt Printer M129C/TM-T70
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x04b8 Seiko Epson Corp.
idProduct 0x0202 Receipt Printer M129C/TM-T70
bcdDevice 2.00
iManufacturer 1 EPSON
iProduct 2 EPSON UB-U01III
iSerial 3 20110125210031250M02C
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0020
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 2
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 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 0
Device Status: 0x0001
Self Powered
问题出在 usblp
由 Linux 内核自动加载的驱动程序。将其添加到黑名单解决了问题。这是我的 /etc/modprobe.d/blacklistusblp.conf
文件。
blacklist usblp
请注意,黑名单 usblp
会禁用所有使用 usblp
驱动程序的 USB 打印机,但幸运的是,包括我在内的大多数人都使用 CUPS 作为打印机驱动程序。
(update) 发现编写一个自动分离内核默认驱动程序而不是黑名单的 udev 规则会更好。这是我的 /etc/udev/rules.d/99-escpos.rules
.
SUBSYSTEM=="usb", ATTRS{idVendor}=="04b8", ATTRS{idProduct}=="0202", MODE="0664", GROUP="wheel", RUN+="/bin/sh -c 'echo -n $id:1.0 > /sys/bus/usb/drivers/usblp/unbind && echo -n $id:1.0 > /sys/bus/usb/drivers/usbfs/unbind'"
此规则还会卸载 usbfs
,当 usblp
分离时,内核偶尔会加载它。