[libhid-discuss] libhid with python: help appreciated
Charles Lepple
clepple at ghz.cc
Fri Sep 9 23:08:56 UTC 2011
On Sep 9, 2011, at 9:37 AM, JamesPK wrote:
> Great - thanks for the feedback. Comments online below:
>
> On 09/09/11 03:22, Charles Lepple wrote:
>>> Hi,
>>>
>>> Apologies for what might be a basic libhid question.
>>>
>>> I'm running Ubuntu, and using libhid via Python to communicate
>>> with a HID device (and have used 'lsusb' to glean all the details
>>> of the device).
>>>
>>> I've started out with the example code here: http://anonscm.debian.org/viewvc/libhid/trunk/swig/test_libhid.py
>>> .I added the vendor and product ID and the example code itself
>>> worked FINE.
>>>
>>> I then added some code to the example. From the 'snooping' on the
>>> communication with the device under Windows it needs a control
>>> message with an initialisation string to initialise the device,
>>> which I thought would be:
>>
>> Not to sound too nit-picky, but is it an actual USB control
>> transfer, or is it just a message that is being sent to the device?
>>
>> USB has the notion of Control endpoints (EP0 IN and OUT), and also
>> Interrupt endpoints. Not all devices have interrupt endpoints, but
>> if you post the output of 'lsusb -v' (run as root, preferably after
>> something like libhid has detached the kernel HID driver), we can
>> see which endpoints are available.
>
> Good question - I'm not sure if its a control message required??? I
> expect it might just be a normal 'write' message (as on double
> checking the on the windows output the 'request' filed was set as
> listed as 'set report' )
Again, with several endpoints possible, the destination of the message
matters. (Windows apparently masks this difference when reading or
writing to HID interfaces - it uses an interrupt endpoint if
available, otherwise it issues a request on EP0.)
From below, you only have "EP 1 IN" (plus the always-present EP0 IN/
OUT).
You probably want to use hid_set_output_report():
http://libhid.alioth.debian.org/doc/hid__exchange_8c.html#7eb62286840ff33db4f68d58682bc4ad
And the path is going to look like { 0xFF000001, 0xFF000002 } (depth 2
since there are two elements). See the comments in the example source
code (or the archives of this list) for the derivation.
An alternate way of approaching this is to use one of the tools which
converts USBSnoop (or similar) log files to sequences of direct libusb
calls. Since your HID device is simply using the HID transport layer
to pass 8-byte messages around, you might find it easier to just use
libusb directly.
Look under "USB sniff log parser": http://www.piclist.com/techref/usbs.htm
> Ok - 'lsusb -v' is at base of post.
>
>>> ret = hid_interrupt_write(hid, 0, INIT_SEQ, 8)
>>> if ret != HID_RET_SUCCESS:
>>> log_error("hid_set_output_report", ret)
>>>
>>> But when I added the above spinet to the example and run it I get:
>>> (ALL messages fine up to here)
>>> ---------------------
>>> NOTICE: hid_force_open(): successfully opened USB device 006/002[0].
>>> TRACE: hid_reset_parser(): resetting the HID parser for USB device
>>> 006/002[0]...
>>> TRACE: hid_dump_tree(): iterating the parse tree for USB device
>>> 006/002[0]...
>>> TRACE: hid_reset_parser(): resetting the HID parser for USB device
>>> 006/002[0]...
>>> TRACE: hid_interrupt_write(): writing interrupt report to device
>>> 006/002[0] ...
>>> WARNING: hid_interrupt_write(): failed to perform interrupt write
>>> to device 006/002[0]: error submitting URB: No such file or
>>> directory
>>> ---------------------
>>
>> Ah, I think I see what's going on: you passed endpoint 0 to
>> hid_interrupt_write() - it should be 1 or higher. Again, lsusb
>> output will pin this down.
>>
>
> Thanks.
>
> James
> -----------------------------------------------------------------
> jamespk at hal:~/project/driver/hidapi$ sudo lsusb -v -d 0fde:ca01
>
> Bus 006 Device 002: ID 0fde:ca01
> Device Descriptor:
> bLength 18
> bDescriptorType 1
> bcdUSB 1.10
> bDeviceClass 0 (Defined at Interface level)
> bDeviceSubClass 0
> bDeviceProtocol 0
> bMaxPacketSize0 8
> idVendor 0x0fde
> idProduct 0xca01
> bcdDevice 3.02
> iManufacturer 0
> iProduct 1 Universal Bridge
> iSerial 0
> bNumConfigurations 1
> Configuration Descriptor:
> bLength 9
> bDescriptorType 2
> wTotalLength 34
> bNumInterfaces 1
> bConfigurationValue 1
> iConfiguration 0
> bmAttributes 0x80
> (Bus Powered)
> MaxPower 100mA
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 0
> bAlternateSetting 0
> bNumEndpoints 1
> bInterfaceClass 3 Human Interface Device
> bInterfaceSubClass 0 No Subclass
> bInterfaceProtocol 0 None
> iInterface 0
> HID Device Descriptor:
> bLength 9
> bDescriptorType 33
> bcdHID 1.10
> bCountryCode 0 Not supported
> bNumDescriptors 1
> bDescriptorType 34 Report
> wDescriptorLength 34
> Report Descriptor: (length is 34)
> Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
> (null)
> Item(Local ): Usage, data= [ 0x01 ] 1
> (null)
> Item(Main ): Collection, data= [ 0x01 ] 1
> Application
> Item(Local ): Usage, data= [ 0x01 ] 1
> (null)
> Item(Global): Logical Minimum, data= [ 0x00 ] 0
> Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
> Item(Global): Report Size, data= [ 0x08 ] 8
> Item(Global): Report Count, data= [ 0x08 ] 8
> Item(Main ): Input, data= [ 0x00 ] 0
> Data Array Absolute No_Wrap Linear
> Preferred_State No_Null_Position
> Non_Volatile Bitfield
^ Up to 8 bytes of input to the PC, probably requested on either EP 1
IN, or EP0 via the GetReport message.
> Item(Local ): Usage, data= [ 0x02 ] 2
> (null)
> Item(Global): Logical Minimum, data= [ 0x00 ] 0
> Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
> Item(Global): Report Size, data= [ 0x08 ] 8
> Item(Global): Report Count, data= [ 0x08 ] 8
> Item(Main ): Output, data= [ 0x02 ] 2
> Data Variable Absolute No_Wrap Linear
> Preferred_State No_Null_Position
> Non_Volatile Bitfield
^ Up to 8 bytes of output from the PC, accepted only on EP0 via the
SetReport message.
> Item(Main ): End Collection, data=none
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 3
> Transfer Type Interrupt
> Synch Type None
> Usage Type Data
> wMaxPacketSize 0x0008 1x 8 bytes
> bInterval 1
> Device Status: 0x0000
> (Bus Powered)
> --------------------------------------------
>
>
More information about the libhid-discuss
mailing list