Discussion:
[libhid-discuss] Using composite USB devices
Ali Asad
2009-03-23 14:51:37 UTC
Permalink
Hi,

This is a follow up to some HID communication questions that I have posted earlier. It relates to use of libhid, but may also be tied to how HID/USB communication is handled in Linux (Ubuntu in particular). Since I am relatively new to both, any pointers I get will be much appreciated.

The device in question is a composite USB memory token that also enumerates as an HID device. It has four end points; ep 1 and ep 2 for bulk mass storage, ep 0 as control end-point, and ep 4 for interrupt IN. The control end-point is used for sending HID data from host to device, and the interrupt end-point for sending HID data from device to the host.

I can talk to this device over HID on both Windows and Mac OS (Tiger as well as Leopard), and now want to support Linux as well.

So far I haved tried using libhid and also the lower level USB library. In both cases I can send data to the device but do not get anything back from device on the interrupt IN end-point. I can confirm this by looking at the USB protocal analyser trace. The data sent to the device gets there fine, but the call to get interrupt data from the device does not work.

I am attaching the pseudo code of using the USB library (libhid gave me similar results). Do you spot anything wrong in this appraoch?

#define MY_CONTROL_INTERFACE 0x00
#define HID_REPORT_SET 0x09
#define HID_RT_OUTPUT 0x02

main ()
{
struct usb_dev_handle *usb_handle;
int vendorID = 0xAAAA;
int productID = 0xBBBB;
int rv;

// this function gets a list of all USB busses and devices,
// picks up the device corresponding to the given vendor/product IDs
// and returns the handle. I get the correct handle.
usb_handle = MyGetDeviceHandle(vendorID, productID);

// detach kernel driver from my device
rv = usb_detach_kernel_driver_np(usb_handle, MY_CONTROL_INTERFACE);

// claim the interface to this device
rv = usb_claim_interface(usb_handle, MY_CONTROL_INTERFACE);

// prepare data to be sent
int MyReportID = 0;
char *data;
... allocate space for 64 bytes of data, and assign value to it

// send data to device over control end-point
rv = usb_control_msg(usb_handle,
USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
HID_REPORT_SET,
MyReportID + (HID_RT_OUTPUT << 8),
MY_CONTROL_INTERFACE,
data,
64,
3000);

// So far so good, the data is sent correct and I can see it in the device.

char inBuffer[64];
int bytesToRead = 14;

// read response data from device
rv = usb_interrupt_read(usb_handle,
0x04, // end-point to read the interrupt from
inBuffer,
bytesToRead,
3000);

// ERROR: this call fails. I do not see any data on the USB bus.
}
Peter Stuge
2009-03-23 15:14:03 UTC
Permalink
Post by Ali Asad
The device in question is a composite USB memory token that also
enumerates as an HID device. It has four end points; ep 1 and ep 2
for bulk mass storage, ep 0 as control end-point, and ep 4 for
interrupt IN.
The control end-point is used for sending HID data from host to
device, and the interrupt end-point for sending HID data from device
to the host.
Are ep1-2 and ep4 in different interfaces? If not I think you're in
trouble if you want to use the MSC at the same time as HID.
Post by Ali Asad
I can talk to this device over HID on both Windows and Mac OS
(Tiger as well as Leopard), and now want to support Linux as well.
Using native HID on OS X?
Post by Ali Asad
I am attaching the pseudo code of using the USB library (libhid
gave me similar results). Do you spot anything wrong in this
appraoch?
Posting to libusb-devel might be better. I'll try to give some hints
here at least.
Post by Ali Asad
rv = usb_detach_kernel_driver_np(usb_handle, MY_CONTROL_INTERFACE);
Do you need to?
Post by Ali Asad
rv = usb_claim_interface(usb_handle, MY_CONTROL_INTERFACE);
This makes me a bit scared. How many interfaces are there? You should
have at least two. Output from lsusb -v and /proc/bus/usb/devices is
always helpful in these questions.
Post by Ali Asad
rv = usb_interrupt_read(usb_handle,
// ERROR: this call fails. I do not see any data on the USB bus.
How does it fail? Please provide every single detail if you want us
to be able to help you.


//Peter
Ali Asad
2009-03-30 14:57:33 UTC
Permalink
Hi,

Based on feedback from this list and also from libusb, I was to resolve these issues with my composite device. I can now send and receive data to it. Many thanks for your suggestions.
Post by Ali Asad
Are ep1-2 and ep4 in different interfaces? If not I think you're in trouble if you want to use the MSC at the same time as HID.
Yes, ep1-2 and ep4 are on different interfaces.
Post by Ali Asad
Using native HID on OS X?
Yes, we use native HID support on OS X.

Best regards,
--- asad

-----Original Message-----
From: libhid-discuss-bounces+asad.ali=gemalto.com at lists.alioth.debian.org [mailto:libhid-discuss-bounces+asad.ali=gemalto.com at lists.alioth.debian.org] On Behalf Of Peter Stuge
Sent: Monday, March 23, 2009 10:14 AM
To: libhid-discuss at lists.alioth.debian.org
Subject: Re: [libhid-discuss] Using composite USB devices
Post by Ali Asad
The device in question is a composite USB memory token that also
enumerates as an HID device. It has four end points; ep 1 and ep 2 for
bulk mass storage, ep 0 as control end-point, and ep 4 for interrupt
IN.
The control end-point is used for sending HID data from host to
device, and the interrupt end-point for sending HID data from device
to the host.
Are ep1-2 and ep4 in different interfaces? If not I think you're in trouble if you want to use the MSC at the same time as HID.
Post by Ali Asad
I can talk to this device over HID on both Windows and Mac OS (Tiger
as well as Leopard), and now want to support Linux as well.
Using native HID on OS X?
Post by Ali Asad
I am attaching the pseudo code of using the USB library (libhid gave
me similar results). Do you spot anything wrong in this appraoch?
Posting to libusb-devel might be better. I'll try to give some hints here at least.
Post by Ali Asad
rv = usb_detach_kernel_driver_np(usb_handle,
MY_CONTROL_INTERFACE);
Do you need to?
Post by Ali Asad
rv = usb_claim_interface(usb_handle, MY_CONTROL_INTERFACE);
This makes me a bit scared. How many interfaces are there? You should have at least two. Output from lsusb -v and /proc/bus/usb/devices is always helpful in these questions.
Post by Ali Asad
rv = usb_interrupt_read(usb_handle,
// ERROR: this call fails. I do not see any data on the USB bus.
How does it fail? Please provide every single detail if you want us to be able to help you.


//Peter

Loading...