Get string descriptor using PyUSB usb.util.get_string ()

I'm having trouble getting the string descriptor of a USB device. What I'm looking for is human-friendly names of manufacturers and products. I use libusb-1.0 as the backend and can get the manufacturer name using the provided libusb testing program, so I know that it exists.

The PyUSB help file says that you can access usb_get_string_simple (from the libusb backend) using:

get_string (dev, length, index, langid = None)

  Retrieve a string descriptor from the device. dev is the Device object to which the request will be sent to. length is the length of string in number of characters. index is the string descriptor index and langid is the Language ID of the descriptor. If langid is omitted, the string descriptor of the first Language ID will be returned. The return value is the unicode string present in the descriptor. 
 import usb #help(usb.core) busses = usb.busses() for bus in busses: devices = bus.devices for dev in devices: _name = usb.util.get_string(dev.dev,256,0) #This is where I'm having trouble print "device name=",_name print "Device:", dev.filename print " Device class:",dev.deviceClass print " Device sub class:",dev.deviceSubClass print " Device protocol:",dev.deviceProtocol print " Max packet size:",dev.maxPacketSize print " idVendor:",hex(dev.idVendor) print " idProduct:",hex(dev.idProduct) print " Device Version:",dev.deviceVersion for config in dev.configurations: print " Configuration:", config.value print " Total length:", config.totalLength print " selfPowered:", config.selfPowered print " remoteWakeup:", config.remoteWakeup print " maxPower:", config.maxPower for intf in config.interfaces: print " Interface:",intf[0].interfaceNumber for alt in intf: print " Alternate Setting:",alt.alternateSetting print " Interface class:",alt.interfaceClass print " Interface sub class:",alt.interfaceSubClass print " Interface protocol:",alt.interfaceProtocol for ep in alt.endpoints: print " Endpoint:",hex(ep.address) print " Type:",ep.type print " Max packet size:",ep.maxPacketSize print " Interval:",ep.interval 

Any help would be appreciated.

+4
source share
4 answers

( July 2019 update: see Theodor-Bogdan Barbier’s answer below for a clear description of why hard indexes shouldn’t really be used!)

( Second update, July 2019: see the comment below on the USB specification, which contains a table with all the fields of the device descriptor.)

The following line in your code:

 usb.util.get_string(dev.dev,256,0) 

this is really a problem. I'm not quite sure what the USB spec says, but in my current hardware project, I get the following for index selection:

  • index = 0 (your choice) returns one Unicode character
  • index = 1 sends to producer
  • index = 2 sends the device description
  • index = 3 sends the serial number of the device

So try:

 usb.util.get_string(dev.dev, 256, 2) 

Good luck

+5
source

It’s not difficult to index the index.

I would recommend using something like this:

 usb.util.get_string(dev, 256, dev.iSerialNumber) usb.util.get_string(dev, 256, dev.iManufacturer) 

As you will see below, the index is different from device to device.

Lsusb -v output:

 device 1: #index #string_descriptor iManufacturer 3 Linux 3.8.13 musb-hcd iProduct 2 MUSB HDRC host driver iSerial 1 musb-hdrc.1.auto device 2: iManufacturer 2 E-boda iProduct 3 SUNNY V35 iSerial 4 0123456789ABCDEF 
+3
source

This will retrieve the rows from the device:

 dev = usb.core.find(idVendor=0x077d, idProduct=0x0410) # fill in your own device, of course if dev is None: print 'Our device is not connected' else: if dev._manufacturer is None: dev._manufacturer = usb.util.get_string(dev, dev.iManufacturer) print str(dev._manufacturer) if dev._product is None: dev._product = usb.util.get_string(dev, dev.iProduct) print str(dev._product) 
0
source

change to usb.util.get_string(dev, dev.iSerialNumber)

0
source

All Articles