Discussion:
[libhid-discuss] Paths to usage pages / python wrapper
Sarah Mount
2008-11-12 16:28:01 UTC
Permalink
Hi all,

I'm using the SWIG/Python wrapper to libhid and just having some
trouble figuring out usage paths. The device I'm trying to communicate
with has the following parse tree:

parse tree of HIDInterface 005/007[0]:
path: 0xff000001.0xff000002; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00000000; type: 0xb0
path: 0xff000001.0x00010046.0x00010001; type: 0x80
path: 0xff000001.0x00010046.0x00010003; type: 0x80
path: 0xff000001.0x00010046.0x00010002; type: 0x80


Presumably anything with type 0xb0 can be used to set a feature
report? If I say something like:

path = (0xff000001, 0xff000002)
buffer = struct.pack('6b27x', 0x1, 0x1, 0x01, 0x01, 0x00, 0x02)
print 'Sending buffer of size %i to sensor: %s' % (len(buffer), repr(buffer))
ret = hid_set_output_report(hid, path, buffer)
if ret != HID_RET_SUCCESS:
sys.stderr.write("hid_dump_tree failed with return code %d.\n" % ret)
else: print 'Sent output report successfully!'

I get the following error:

Traceback (most recent call last):
File "./toradex.py", line 94, in <module>
main()
File "./toradex.py", line 54, in main
ret = hid_set_output_report(hid, path, buffer)
File "/var/lib/python-support/python2.5/hid/__init__.py", line 206,
in hid_set_output_report
return _hid.hid_set_output_report(*args)
ValueError: Expecting a sequence of integers

Presumably because the path in question was a sequence of longs. I'm
not sure whether the problem here is my understanding of the way paths
work in HID or something else! I'd be very grateful if anyone can
point me in the right direction. (output of lsusb listed below, in
case it's helpful).

Very many thanks,

Sarah


Output of `lsusb -d 0x1b67:0x0001 -vvv`

Bus 003 Device 008: ID 1b67:0001
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x1b67
idProduct 0x0001
bcdDevice 1.00
iManufacturer 1 Toradex
iProduct 2 Humidity Sensor
iSerial 3 T83310006
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 32mA
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 2 Humidity Sensor
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 112
Report Descriptor: (length is 112)
Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
(null)
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x20 ] 32
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
Item(Local ): Usage, data= [ 0x02 ] 2
(null)
Item(Main ): Feature, data= [ 0xe2 0x01 ] 482
Data Variable Absolute No_Wrap Linear
No_Preferred_State Null_State Volatile Buffered Bytes
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x46 ] 70
Vector
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x07 ] 2047
Item(Global): Physical Minimum, data= [ 0x00 ] 0
Item(Global): Physical Maximum, data= [ 0xff 0x07 ] 2047
Item(Global): Unit, data= [ 0x01 0x10 ] 4097
System: SI Linear, Unit: Seconds
Item(Global): Unit Exponent, data= [ 0x0d ] 13
Unit Exponent: 13
Item(Global): Report Size, data= [ 0x10 ] 16
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Local ): Usage, data= [ 0x01 ] 1
Pointer
Item(Local ): String Index, data= [ 0x04 ] 4
Item(Main ): Input, data= [ 0xea 0x01 ] 490
Data Variable Absolute Wrap Linear
No_Preferred_State Null_State Volatile Buffered Bytes
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x10 0x27 ] 10000
Item(Global): Physical Minimum, data= [ 0x00 ] 0
Item(Global): Physical Maximum, data= [ 0x10 0x27 ] 10000
Item(Global): Unit, data= [ 0x00 ] 0
System: None, Unit: (None)
Item(Global): Unit Exponent, data= [ 0x0c ] 12
Unit Exponent: 12
Item(Global): Report Size, data= [ 0x10 ] 16
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Local ): Usage, data= [ 0x03 ] 3
(null)
Item(Local ): String Index, data= [ 0x05 ] 5
Item(Main ): Input, data= [ 0xe2 0x01 ] 482
Data Variable Absolute No_Wrap Linear
No_Preferred_State Null_State Volatile Buffered Bytes
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x64 0xd5 0x00 0x00 ] 54628
Item(Global): Physical Minimum, data= [ 0x00 ] 0
Item(Global): Physical Maximum, data= [ 0x64 0xd5 0x00 0x00 ] 54628
Item(Global): Unit, data= [ 0x01 0x00 0x01 0x00 ] 65537
System: SI Linear, Unit: Kelvin
Item(Global): Unit Exponent, data= [ 0x0e ] 14
Unit Exponent: 14
Item(Global): Report Size, data= [ 0x10 ] 16
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Local ): Usage, data= [ 0x02 ] 2
Mouse
Item(Local ): String Index, data= [ 0x06 ] 6
Item(Main ): Input, data= [ 0xe2 0x01 ] 482
Data Variable Absolute No_Wrap Linear
No_Preferred_State Null_State Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Main ): End Collection, data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
Device Status: 0x0000
(Bus Powered)
--
Sarah Mount, Senior Lecturer, University of Wolverhampton
Web: http://www.wlv.ac.uk/~in0316/
Book: http://www.pythonforrookies.org/
Blog: http://varspool.blogspot.com/
Photos: http://flickr.com/photos/sarahmount/

This email, together with any attachment, is for the exclusive and
confidential use of the addressee(s) and may contain legally
privileged information. Any use, disclosure or reproduction without
the sender's explicit consent is unauthorised and may be unlawful.

Any e-mail including its content and any attachments may be monitored
and used by The University of Wolverhampton for reasons of security
and for monitoring internal compliance with the University's policy on
internet use. E-mail blocking software may also be used. The
University cannot guarantee that this message or any attachment is
virus free or has not been intercepted and amended.

If you believe you have received this message in error please notify
the sender by email, telephone or fax and destroy the message and any
copies.
Charles Lepple
2008-11-13 02:13:05 UTC
Permalink
Post by Sarah Mount
Hi all,
I'm using the SWIG/Python wrapper to libhid and just having some
trouble figuring out usage paths. The device I'm trying to communicate
Please provide some details about the version of libhid, and where
you got it (since it looks like it was installed as part of a Linux
distribution).

[...]
Post by Sarah Mount
Presumably anything with type 0xb0 can be used to set a feature
Almost; usage paths that end in 0x00000000 are vestiges of a bug in
hid_dump_tree for arrays.
Post by Sarah Mount
path = (0xff000001, 0xff000002)
buffer = struct.pack('6b27x', 0x1, 0x1, 0x01, 0x01, 0x00, 0x02)
print 'Sending buffer of size %i to sensor: %s' % (len(buffer), repr(buffer))
ret = hid_set_output_report(hid, path, buffer)
sys.stderr.write("hid_dump_tree failed with return code %d.\n" % ret)
else: print 'Sent output report successfully!'
This looks like it should work.
Post by Sarah Mount
File "./toradex.py", line 94, in <module>
main()
File "./toradex.py", line 54, in main
ret = hid_set_output_report(hid, path, buffer)
File "/var/lib/python-support/python2.5/hid/__init__.py", line 206,
in hid_set_output_report
return _hid.hid_set_output_report(*args)
ValueError: Expecting a sequence of integers
Not sure, this probably would involve recompilation to figure out
what is going wrong. Also, what version of swig is installed?
Post by Sarah Mount
Presumably because the path in question was a sequence of longs. I'm
not sure whether the problem here is my understanding of the way paths
work in HID or something else! I'd be very grateful if anyone can
point me in the right direction. (output of lsusb listed below, in
case it's helpful).
I couldn't get Python 2.5 to work with SWIG on OS X, so I started
looking at alternatives.

Python 2.5 includes ctypes, which provides Python access to native
libraries. You may be interested in this:

http://boxster.ghz.cc/projects/libhid/browser/trunk/swig/hid_ctypes.py

That should work with your existing libhid.so, with some minor path
adjustments in the beginning.
--
Charles Lepple
Sarah Mount
2008-11-16 14:39:03 UTC
Permalink
Post by Sarah Mount
Hi all,
I'm using the SWIG/Python wrapper to libhid and just having some
trouble figuring out usage paths. The device I'm trying to communicate
Please provide some details about the version of libhid, and where you got
it (since it looks like it was installed as part of a Linux distribution).
Hi Charles, thanks for this and your other message. Using
set_feature_report solved the ValueError problem with longs/ints. I
can't think why, but at least it works!

I'm using Ubuntu Ibex with the following installed (from the Ubuntu repository):

python-hid 0.2.15+20060325-2.1
libhid0 0.2.15+20060325-2.1
libusb 1:0.1.5-1

Not that it matters now, but perhaps useful to note for anyone with a
similar problem searching the archives.

Thanks,

Sarah
--
Sarah Mount, Senior Lecturer, University of Wolverhampton
Web: http://www.wlv.ac.uk/~in0316/
Book: http://www.pythonforrookies.org/
Blog: http://varspool.blogspot.com/
Photos: http://flickr.com/photos/sarahmount/

This email, together with any attachment, is for the exclusive and
confidential use of the addressee(s) and may contain legally
privileged information. Any use, disclosure or reproduction without
the sender's explicit consent is unauthorised and may be unlawful.

Any e-mail including its content and any attachments may be monitored
and used by The University of Wolverhampton for reasons of security
and for monitoring internal compliance with the University's policy on
internet use. E-mail blocking software may also be used. The
University cannot guarantee that this message or any attachment is
virus free or has not been intercepted and amended.

If you believe you have received this message in error please notify
the sender by email, telephone or fax and destroy the message and any
copies.
Charles Lepple
2008-11-13 02:16:44 UTC
Permalink
Post by Sarah Mount
Presumably anything with type 0xb0 can be used to set a feature
path = (0xff000001, 0xff000002)
buffer = struct.pack('6b27x', 0x1, 0x1, 0x01, 0x01, 0x00, 0x02)
print 'Sending buffer of size %i to sensor: %s' % (len(buffer), repr(buffer))
ret = hid_set_output_report(hid, path, buffer)
sys.stderr.write("hid_dump_tree failed with return code %d.\n" % ret)
else: print 'Sent output report successfully!'
My mistake - to set a feature report, you'd need
hid_set_feature_report (different USB request than sending output
reports).

Still not sure why you got a ValueError, though. Most of the SWIG
functions recognize that integers and longs can be cast to one another.
--
Charles Lepple
Loading...