I have android device and windows drivers for it. I have to communicate using my own binary protocol in accessory mode. Is it possible to send data to this device without writing custom USB driver?
USB is a complex protocol because it is 'universal' and can handle a large variety of devices (mass storage, cameras,...). So on your android device has to be implemented a basic USB structure to use standard libraries like libusb or something like that. You can assume that this is the case, because android is in most cases used on processors with USB port.
See http://www.beyondlogic.org/usbnutshell/usb1.shtml.
You can get more information about the USB device classes, interfaces, configurations, endpoints ur android device impmenets by using libusb -v
Then if you know what the USB structure on your android device looks like you can use libusb or another library to write data to specific endpoints in the usb structure by e.g. libusb_bulk_transfer()
, libusb_control_transfer()
http://libusb.sourceforge.net/api-1.0/io.html
If you want to program in java you can use usb4java however this is a bit flaky http://usb4java.org/quickstart/libusb.html
The general USB structure is device -> (configuration) -> interface -> endpoint
So the way to write data to an endpoint is:
libusb_init(NULL);
libusb_open_device_with_vid_pid(NULL, vendor_id, product_id);
libusb_claim_interface(devh, 0);
libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT), data,
4, &p, 0); //example
... release interface...
...
libusb_close(devh);
libusb_exit(NULL);
Here is C++ example copied from http://www.dreamincode.net/forums/topic/148707-introduction-to-using-libusb-10/
#include <iostream>
#include <libusb.h>
using namespace std;
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, 5118, 7424);
//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;
}
So as your device runs android it has a USB structure/functionality. To investigate the USB functionality of your device (device class like mass storage, RNDIS,...) use libusb -v
and the see the code above to write custom data to one of the endpoints on the device.