[libhid-discuss] libhid with python: help appreciated

JamesPK jpearsonkirk at googlemail.com
Mon Sep 12 12:00:16 UTC 2011


Thanks for your help. I'll try out your suggestions.

James

On 10/09/11 00:08, Charles Lepple wrote:
> 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