【问题标题】:Get string descriptor using PyUSB usb.util.get_string()使用 PyUSB usb.util.get_string() 获取字符串描述符
【发布时间】:2011-08-22 01:53:48
【问题描述】:

我无法获取 USB 设备的字符串描述符。我正在寻找的是人类友好的制造商和产品名称。我使用 libusb-1.0 作为后端,并且能够使用提供的 libusb 测试程序获取制造商名称,所以我知道它存在。

PyUSB 帮助文件说您可以使用以下方法访问 usb_get_string_simple(来自 libusb 后端):

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

我们将不胜感激。

【问题讨论】:

  • 您能否发布示例输出并说明它与您想要的有何不同?
  • 输出返回为:“device name=Љ” 当我使用 libusb 测试应用程序时,它返回“LG Electronics, Inc”

标签: python windows pyusb libusb-1.0


【解决方案1】:

对索引进行硬编码不是一个好主意。

我会推荐使用这样的东西:

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

正如您将在下面看到的,索引因设备而异。

lsusb -v 的输出:

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

【讨论】:

    【解决方案2】:

    2019 年 7 月更新:请参阅下面 Teodor-Bogdan Barbieru 的回答,清楚说明为什么您实际上不应该对索引进行硬编码!)

    2019 年 7 月第二次更新:请参阅下面 gog 的评论以获取指向 USB 规范的链接,其中包含列出所有设备描述符字段的表格。)

    代码中的以下行:

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

    确实是问题所在。我不太确定 USB 规范是怎么说的,但在我当前的硬件项目中,我得到以下索引选择:

    • index=0(您的选择)返回单个 unicode 字符
    • index=1 发送制造商
    • index=2 发送设备描述
    • index=3 发送设备序列号

    那么,试试吧:

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

    祝你好运!

    【讨论】:

    • 不!不要硬编码任何索引。如果你在一个硬件项目中,你应该知道你可以为你的字符串描述符选择任何你想要的索引。正确的答案是使用dev.iProduct 作为索引。此外,索引 0 不会返回单个 unicode 字符,而是会从 USB 设备返回支持的 LANGID 列表。请编辑您的答案,因为您报告了错误信息
    • 当然,我会编辑我的答案。七年前,我只是在描述我从连接的设备中得到了什么。 PyUSB 文档在这一点上不是很清楚。如果您能指出我更好的描述,我会将该链接添加到我的答案中。同时,我将在下面指出 Teodor-Bogdan Barbieru 的回答。
    • PyUSB 文档可能不清楚,因为 USB 规范已经说明了一切;)。你可以找到它here。具体来说,在 usb_20.pdf 文件中,第 9.6.1 章有一个描述所有 DEVICE 描述符字段的表。第 9.6.7 章描述了 STRING 描述符,以及 STRING 描述符在索引 0 处的不同行为
    • 我已经用指向您评论的指针更新了答案。谢谢,@gog!
    【解决方案3】:

    这将从设备中检索字符串:

    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)
    

    【讨论】:

    • 这会导致TypeError: get_string() takes at least 3 arguments (2 given),因为参数长度不是可选的。
    【解决方案4】:

    修改为usb.util.get_string(dev, dev.iSerialNumber)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多