Question

I have a USB device (6 lights: 2 IR, 2 white lights, 2 LEDs) and I can't get my hands on the windows driver (also I dislike windows) so I want to try to control it via C and libusb (see the script below, which I got from here). Is there a brute force way (or better yet a program) to find out what signals it is expecting? Essentially loop over some values and send those while I observe whether the light is turned on or not?

control_lights.cpp:

#include <iostream>
#include <libusb-1.0/libusb.h>

using namespace std;

#define VENDOR_ID 1133
#define PRODUCT_ID 2449

int main() {
   libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
   libusb_device_handle *dev_handle; //a device handle
   libusb_context *ctx = NULL; //a libusb session
   int r; //for return values
   ssize_t cnt; //holding number of devices in list
   r = libusb_init(&ctx); //initialize the library for the session we just declared
   if(r < 0) {
      cout<<"Init Error "<<r<<endl; //there was an error
      return 1;
   }
   libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation

   cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
   if(cnt < 0) {
      cout<<"Get Device Error"<<endl; //there was an error
      return 1;
   }
   cout<<cnt<<" Devices in list."<<endl;

   dev_handle = libusb_open_device_with_vid_pid(ctx, VENDOR_ID, PRODUCT_ID ); //these are vendorID and productID I found for my usb device
   if(dev_handle == NULL)
      cout<<"Cannot open device"<<endl;
   else
      cout<<"Device Opened"<<endl;
   libusb_free_device_list(devs, 1); //free the list, unref the devices in it

   unsigned char *data = new unsigned char[4]; //data to write
   data[0]='a';data[1]='b';data[2]='c';data[3]='d'; //some dummy values

   int actual; //used to find out how many bytes were written
   if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached
      cout<<"Kernel Driver Active"<<endl;
      if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
         cout<<"Kernel Driver Detached!"<<endl;
   }
   r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
   if(r < 0) {
      cout<<"Cannot Claim Interface"<<endl;
      return 1;
   }
   cout<<"Claimed Interface"<<endl;

   cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd
   cout<<"Writing Data..."<<endl;
   r = libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT_OUT), data, 4, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
   if(r == 0 && actual == 4) //we wrote the 4 bytes successfully
      cout<<"Writing Successful!"<<endl;
   else
      cout<<"Write Error"<<endl;

   r = libusb_release_interface(dev_handle, 0); //release the claimed interface
   if(r!=0) {
      cout<<"Cannot Release Interface"<<endl;
      return 1;
   }
   cout<<"Released Interface"<<endl;

   libusb_close(dev_handle); //close the device we opened
   libusb_exit(ctx); //needs to be called to end the

   delete[] data; //delete the allocated memory for data
   return 0;
}

EDIT: I have a feeling this information will be useful. I found out what the name of the usb device is, and after a little editing, this is the pertinent out of lsusb -v:

Bus 002 Device 007: ID 03eb:f003 Atmel Corp. 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        32
  idVendor           0x03eb Atmel Corp.
  idProduct          0xf003 
  bcdDevice            1.03
  iManufacturer           1 REMOVED www.REMOVED.com powered by Atmel
  iProduct                2 SSS-Cube Document Reader 500mW UV
  iSerial                 3 290720080x
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            8 French
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      53
         Report Descriptors: 
           ** UNAVAILABLE **
      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              20
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              20
Device Status:     0x0000
  (Bus Powered)
Was it helpful?

Solution

libusb_bulk_transfer(...)

You have a HID device, which has no bulk endpoints. You would need either control transfer or interrupt transfer, maybe both.

If you are very lucky, the HID report deskriptor - which lsusb does not show you, unfortunately - might contain enough information to deduce how to format the data for those endpoints.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top