Skip to content

Commit 70359cf

Browse files
committed
Workaround for "Pantum BP5100DN series" initialization failure
Starting from version 0.9.31, ipp-usb requires that printers return non-empty Manufacturer, ProductName, and SerialNumber strings. Without these, quirks, state files, and per-device logging do not work properly, as they are bound to the combination of these strings. Additionally, for some devices (Xerox B205/B210/B215), failure to return these strings may indicate improper initialization and require a reset. Unfortunately, other devices (notably the "Pantum BP5100DN series") may fail to return a string descriptor on the first attempt. Investigation revealed that the request for language IDs, implicitly performed by libusb_get_string_descriptor_ascii, returns a malformed packet. This causes libusb to fail with LIBUSB_ERROR_IO. As a workaround, we retry several times before giving up.
1 parent c4974f5 commit 70359cf

1 file changed

Lines changed: 21 additions & 9 deletions

File tree

usbio_libusb.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -611,15 +611,27 @@ func (devhandle *UsbDevHandle) UsbDeviceInfo() (UsbDeviceInfo, error) {
611611
}
612612

613613
for _, s := range strings {
614-
rc := C.libusb_get_string_descriptor_ascii(
615-
(*C.libusb_device_handle)(devhandle),
616-
s.idx,
617-
(*C.uchar)(unsafe.Pointer(&buf[0])),
618-
C.int(len(buf)),
619-
)
620-
621-
if rc > 0 {
622-
*s.str = string(buf[:rc])
614+
// Some devices (notably the "Pantum BP5100DN series") may
615+
// fail to return a string descriptor on the first attempt.
616+
//
617+
// Investigation revealed that the request for language IDs,
618+
// implicitly performed by libusb_get_string_descriptor_ascii,
619+
// returns a malformed packet. This causes libusb to fail
620+
// with LIBUSB_ERROR_IO.
621+
//
622+
// As a workaround, we retry several times before giving up.
623+
for i := 0; i < 3; i++ {
624+
rc := C.libusb_get_string_descriptor_ascii(
625+
(*C.libusb_device_handle)(devhandle),
626+
s.idx,
627+
(*C.uchar)(unsafe.Pointer(&buf[0])),
628+
C.int(len(buf)),
629+
)
630+
631+
if rc > 0 {
632+
*s.str = string(buf[:rc])
633+
break
634+
}
623635
}
624636
}
625637

0 commit comments

Comments
 (0)