[libhid-discuss] Using composite USB devices

Ali Asad Asad.Ali at gemalto.com
Mon Mar 23 14:51:37 UTC 2009


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.
}




More information about the libhid-discuss mailing list