I'm currently trying to write a service that should programmatically intercepts the output of a barcode scanner. I managed to get pyusb to work on Windows (has to install libusb-1.0 as a backend) and I can enumerate all connected USB devices along with the hierarchy of descriptors. So far so good.
Next step was to get data from the end point. I couldn't quite figure out how pyusb is supposed to work in that specific instance and even after reading the device's user manual (it's a HHP 3800g if it could help), I couldn't come with any wisdow on how to achieve this. pyusb read doesn't work.
Seeing both interface are HID ifaces, I attempted to use hidapi to access the device input. I manage to open the device using the path descriptor but read operation doesn't work.
iface 0 is HDI Keyboard emulation (usage=2)
iface 1 is HDI POS (usage=6)
I even tried to sniff USB traffic with Wireshark/USBPcap, not to avail. I can see USB traffic from the mouse (wee!) but no frames from the barcode scanner.
I should add that the scanner works properly being seen as a darn keyboard and behaving accordingly.
Here below is the entire descriptor of the device extracted by pyusb. The snippet of code comes after.
DEVICE ID 0536:02e1 on Bus 001 Address 002 =================
bLength : 0x12 (18 bytes)
bDescriptorType : 0x1 Device
bcdUSB : 0x110 USB 1.1
bDeviceClass : 0x0 Specified at interface
bDeviceSubClass : 0x0
bDeviceProtocol : 0x0
bMaxPacketSize0 : 0x20 (32 bytes)
idVendor : 0x0536
idProduct : 0x02e1
bcdDevice : 0x0 Device 0.0
iManufacturer : 0x1 Hand Held Products
iProduct : 0x2 3800G
iSerialNumber : 0x8 08011D1080
bNumConfigurations : 0x1
CONFIGURATION 1: 250 mA ==================================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x2 Configuration
wTotalLength : 0x49 (73 bytes)
bNumInterfaces : 0x2
bConfigurationValue : 0x1
iConfiguration : 0x3 Default
bmAttributes : 0xa0 Bus Powered, Remote Wakeup
bMaxPower : 0x7d (250 mA)
INTERFACE 0: Human Interface Device ====================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x4 Interface
bInterfaceNumber : 0x0
bAlternateSetting : 0x0
bNumEndpoints : 0x2
bInterfaceClass : 0x3 Human Interface Device
bInterfaceSubClass : 0x1
bInterfaceProtocol : 0x1
iInterface : 0x4 HID Keyboard Emulation
ENDPOINT 0x83: Interrupt IN ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x83 IN
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x8 (8 bytes)
bInterval : 0x8
ENDPOINT 0x4: Interrupt OUT ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x4 OUT
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x8 (8 bytes)
bInterval : 0x8
ENDPOINT 0x2: Interrupt OUT ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x2 OUT
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x40 (64 bytes)
bInterval : 0x1
HIDAPI python code
device_list = hid.enumerate(DEVICE_ID[0], DEVICE_ID[1]) # got 2 devices (2 ifaces)
device_desc = next(dev for dev in device_list if dev['usage'] == 2) # alternately tried 2/6
device = hid.device()
device.open_path(device_desc['path'])
device.set_nonblocking(1) # tried with 0, no difference
while True:
d = device.read(64)
if d:
print(d)
times.sleep(0.05)
Caveats
- pyusb could work only with a proper backend, doesn't run natively on Windows. Was easy to fix
- USBPcap installs its own driver to capture USB traffic rendering pyusb unable to work (I didn't try to manually set the backend argument though)
Final notes
I have to say that using input/raw_input to get the scanned barcode is not an option. It works but I need to discriminate between legitimate keyboard input and barcode scanner input hence my aim to access the second HID iface.
I tried also to access the USB ports using Windows Linux Subsystem not to avail. I'm on Windows 10 and USB related stuff is disabled (no 'lsusb' for short)
I'm kind of desperate to have it to work, maybe I'm missing something trivial but I'm not a well-seasoned USB specialist as I've only read 'USB in a nutshell' and looked at some code samples that interface with non HID devices.
Any help and insights fairly appreciated.