BulkTransfer & Android USB API - android

I have a program in which I attempt to attach my android device to a webcam via USB. I'm having trouble with a few things, namely properly transferring data. I've tried using bulkTransfer and there seems to be no recognition of it being used. I've been trying to find examples that may assist me such as here but none are helping me - their structure seems to be better than mine but whenever I switch my program crashes on load.
I'm fairly confident my bytes declaration is also incorrect and I should be somehow forwarding my data there, but I'm unsure how. Any help in terms of how to data transfer and how to structure my code would be appreciated.
Some declarations:
private byte[] bytes = {1,2};
private static int TIMEOUT = 0;
private boolean forceClaim = true;
In On Create:
UsbDevice device = (UsbDevice) getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE);
UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()) {
device = deviceIterator.next();
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this,0,new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
mUsbManager.requestPermission(device, mPermissionIntent);
UsbDeviceConnection connection = mUsbManager.openDevice(device);
Log.d("CAM Connection", " " + connection);
Log.d("CAM UsbManager", " " + mUsbManager);
Log.d("CAM Device", " " + device);
UsbInterface intf = device.getInterface(0);
Log.d("CAM_INTF Interface!!!!", " " + intf );
UsbEndpoint endpoint = intf.getEndpoint(0);
Log.d("CAM_END Endpoint", " " + endpoint );
connection.claimInterface(intf, forceClaim);
StringBuilder sb = new StringBuilder();
if(connection.bulkTransfer(endpoint,bytes,bytes.length,TIMEOUT) < 2)
Log.d("test", "");
//Log.d("BULK", ""+ connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT)); //do in another thread
}
Additional relevant code:
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
//call method to set up device communication
}
}
else {
Log.d("Deny:", "permission denied for device " + device);
}
}
}
}
};

one of your problem is on finding endpoints. endpoint0 is for controlling task and you should find the appropriate IN and OUT endpoints in your code.
UsbInterface usbInterfaceTemp = null;
usbInterface = null;
endpointIN = null;
endpointOUT = null;
for (int i = 0; i < usbGotPermiDVC.getInterfaceCount(); i++) {
usbInterfaceTemp = usbGotPermiDVC.getInterface(i);
if (usbInterfaceTemp.getEndpointCount() >= 2) {
for (int j = 0; j < usbInterfaceTemp.getEndpointCount(); j++) {
UsbEndpoint usbEndpointTemp = usbInterfaceTemp.getEndpoint(j);
if (usbEndpointTemp.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (usbEndpointTemp.getDirection() == UsbConstants.USB_DIR_IN) {
endpointIN = usbEndpointTemp;
} else if (usbEndpointTemp.getDirection() == UsbConstants.USB_DIR_OUT) {
endpointOUT = usbEndpointTemp;
}
}
}
}
}
if (endpointIN != null && endpointOUT != null) {
usbInterface = usbInterfaceTemp;
}
if (usbInterface == null) {
return;
}
usbDeviceConnection = usbManager.openDevice(usbSelectedDevice);
if (!(usbDeviceConnection != null && usbDeviceConnection.claimInterface(usbInterface, true))) {
usbDeviceConnection = null;
return;
}
usbDeviceConnection.controlTransfer(0x21, 34, 0, 0, null, 0, 0);
usbDeviceConnection.controlTransfer(0x21, 32, 0, 0, new byte[]{(byte) 0x80,
0x25, 0x00, 0x00, 0x00, 0x00, 0x08}, 7, 0);
Toast.makeText(getApplicationContext(), "Device opened and Interface claimed!", Toast.LENGTH_SHORT).show();
in which usbGotPermiDVC is the device that got the permission to access via USB.

Related

Mtp/Ptp Android

I'm trying to copy the files of my camera who use PTP to my tablet. I have use the android API MTPDevice
(https://developer.android.com/reference/android/mtp/MtpDevice.html#importFile%28int,%20java.lang.String%29) , I have request necessary permission(android.mtp.MtpClient.action.USB_PERMISSION).
I have open the device, the function return true, and open the USBConnection (Connexion OK).
I try to import all files of the camera in a temp Folder on my tablet (/mnt/sdcard/tmpFolder). The path exist on my tablet, but when i give it to the importFiles function I have the error :
[LOGCAT]
MtpDevice: readObject: /mnt/sdcard/tmpFolder
MtpDevice: open failed for /mnt/sdcard/tmpFolder
Debug: File import KO
I have try with a path doesn't exist I have the message :
[LOGCAT]
MtpDevice: readObject: /mnt/sdcard/tptp
MtpDevice: readResponse failed
Debug: File import KO
Someone can help me ?
Thanks
#Background
#DebugLog
public void getMTPDevice() {
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
if (deviceIterator.hasNext()) {
UsbDevice usbDevice = deviceIterator.next();
device = openDeviceLocked(usbDevice);
if(device!=null){
File folder = returnTempFolderCamera();
if(folder.exists()){
Log.d("Debug", "Folder exist /mnt/sdcard/tmpFolder");
if(device.importFile(0,folder.getPath()))
{
Toast.makeText(this, "File import OK", Toast.LENGTH_LONG).show();
Log.d("Debug", "Files import OK");
}else {
Toast.makeText(this, "File import KO", Toast.LENGTH_LONG).show();
Log.d("Debug", "Files import KO");
}
}
}
}
}/**
* Opens the {#link android.hardware.usb.UsbDevice} for an MTP or PTP device
* and return an {#link android.mtp.MtpDevice} for it.
*
* #param usbDevice
* the device to open
* #return an MtpDevice for the device.
*/
#DebugLog
private MtpDevice openDeviceLocked(UsbDevice usbDevice) {
String deviceName = usbDevice.getDeviceName();
byte[] data = new byte[128];
int TIMEOUT = 0;
boolean forceClaim = true;
// don't try to open devices that we have decided to ignore
// or are currently asking permission for
if (isCamera(usbDevice)
&& !mRequestPermissionDevices.contains(deviceName)) {
if (!manager.hasPermission(usbDevice)) {
manager.requestPermission(usbDevice, mPermissionIntent);
mRequestPermissionDevices.add(deviceName);
} else {
UsbInterface intf = usbDevice.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(0);
UsbDeviceConnection connection = manager.openDevice(usbDevice);
connection.claimInterface(intf, forceClaim);
connection.bulkTransfer(endpoint, data, data.length, TIMEOUT);
if (connection != null) {
MtpDevice mtpDevice = new MtpDevice(usbDevice);
if (mtpDevice.open(connection)) {
mDevices.put(usbDevice.getDeviceName(), mtpDevice);
return mtpDevice;
}
}
}
}
return null;
}
private File returnTempFolder(){
File tmp = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/tmpFolder");
return tmp;
}
For people who have the same problem :
Solution is (Found on github) :
MtpClient (https://android.googlesource.com/platform/packages/apps/Gallery2/+/jb-dev/src/com/android/gallery3d/data/MtpClient.java)
#Background
#DebugLog
public void importFiles() {
MtpClient mtpClient = new MtpClient(this);
mtpClient.getDeviceList();
for (int i = 0; i < mtpClient.getDeviceList().size(); i++) {
int[] tab = mtpClient.getDeviceList().get(i).getObjectHandles(mtpClient.getDeviceList().get(i).getStorageIds()[0], 0, 0);
for (int j = 0; j < tab.length; j++) {
File dest = Environment.getExternalStorageDirectory();
// NAME_IMPORTED_FOLDER = tmpFolder
dest = new File(dest, NAME_IMPORTED_FOLDER);
dest.mkdirs();
MtpObjectInfo objInfo = mtpClient.getDeviceList().get(i).getObjectInfo(tab[j]);
if (objInfo != null) {
String destPath = new File(dest, objInfo.getName()).getAbsolutePath();
int objectId = objInfo.getObjectHandle();
// Succes !!
boolean result = mtpClient.getDeviceList().get(i).importFile(objectId, destPath);
}
}
}
mtpClient.close();
}
Regarding above post,
I downloaded the github gallery3d project ,
and look into code of MtpClient.java,
then I find the difference,
The code section from github
String destPath = new File(dest,objInfo.getName()).getAbsolutePath();
int objectId = objInfo.getObjectHandle();
boolean result = mtpClient.getDeviceList().get(i).importFile(objectId, destPath);
The point is 2nd parameter of importFile(objectId, destPath ) "destPath", need to include folder path + filename, then filename should not be changed original filename
But in the origianl question author, you just set folder path
in 2nd parameter

USBConnection nullPointerException

I try to send command to my USB custom device. I think I set all properly - for example I can get ID of device, so Android "sees" it. However , when I try to send it command I get null pointer at line :
connection.bulkTransfer(usbEndpointOut,send,send.length,SEND_TIMEOUT);
Endpoints are set correctly (I've checked it on log). This is my class. Please, help.
mTestButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
UsbDevice device;
if (usbDevices != null) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
int devicePID = device.getProductId();
if (deviceVID != 0x1d6b || (devicePID != 0x0001 || devicePID != 0x0002 || devicePID != 0x0003)) {
Toast.makeText(MainActivity.this, "ID: " + device.getDeviceId()
, Toast.LENGTH_SHORT).show();
Log.e(TAG, "onCreate: " + device.getDeviceId());
UsbInterface usbInterface = null;
UsbEndpoint usbEndpointIn = null;
UsbEndpoint usbEndpointOut = null;
for (int i = 0; i < device.getInterfaceCount(); i++) {
usbInterface = device.getInterface(i);
//l("Interface[" + i + "] -> " + usbInterface);
if (usbInterface != null) {
for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
UsbEndpoint usbEndpoint = usbInterface.getEndpoint(j);
//l("Endpoint[" + j + "] -> " + usbEndpoint);
if (usbEndpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (usbEndpoint.getDirection() == UsbConstants.USB_DIR_IN) {
//l("Found input!");
usbEndpointIn = usbEndpoint;
} else {
//l("Found output!");
usbEndpointOut = usbEndpoint;
}
if (usbEndpointIn != null && usbEndpointOut != null) {
break;
}
}
}
if (usbEndpointIn != null && usbEndpointOut != null) {
break;
}
} else {
//l("Interface was null");
}
}
connection = usbManager.openDevice(device);
connection.bulkTransfer(usbEndpointOut, send, send.length, SEND_TIMEOUT);
keep = false;
} else {
{
connection = null;
device = null;
}
if (!keep)
break;
}
}
}
}
});
}
private static final byte[] send = new byte[]{
(byte) 0xDA, (byte) 0xAD, // const
(byte) 0x02, (byte) 0x74, (byte) 0x00, // com
(byte) 0xBF, (byte) 0xDB // last
};
First of all, the loop which searches usbEndpointIn and usbEndpointOut might fail and then yields null. So, you should call bulkTransfer only if you have valid endpoints.
But the main thing is that you missed to claim the interface that you want to communicate with via bulkTransfer:
if (usbEndpointOut != null) {
connection = usbManager.openDevice(device);
if (connection != null) {
if (connection.claimInterface(usbInterface, true) == true) {
connection.bulkTransfer(usbEndpointOut, send, send.length, SEND_TIMEOUT);
keep = false;
}
}
}

Android USB host read from device

I'm trying to get some data out of a USB device connected to my Android phone that is on host mode. I'm able to send data to it, but reading fails.
I've looked at several examples and tried all I could but I don't have any experience in USB communication, although by now I know a little, and I've been stuck on this longer that I care to admit.
I'm not very familiar with the endpoint configuration, but I know is that my device uses a CDC type communication method and both the output (from phone to device) and input are registered.
Here's the whole class that manages the USB connection with the only device that is connected to the phone, it's not finished by any means, but I'd like to get that reading part to work before I go any further.
public class UsbCommunicationManager
{
static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
UsbManager usbManager;
UsbDevice usbDevice;
UsbInterface intf = null;
UsbEndpoint input, output;
UsbDeviceConnection connection;
PendingIntent permissionIntent;
Context context;
byte[] readBytes = new byte[64];
public UsbCommunicationManager(Context context)
{
this.context = context;
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
// ask permission from user to use the usb device
permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
context.registerReceiver(usbReceiver, filter);
}
public void connect()
{
// check if there's a connected usb device
if(usbManager.getDeviceList().isEmpty())
{
Log.d("trebla", "No connected devices");
return;
}
// get the first (only) connected device
usbDevice = usbManager.getDeviceList().values().iterator().next();
// user must approve of connection
usbManager.requestPermission(usbDevice, permissionIntent);
}
public void stop()
{
context.unregisterReceiver(usbReceiver);
}
public String send(String data)
{
if(usbDevice == null)
{
return "no usb device selected";
}
int sentBytes = 0;
if(!data.equals(""))
{
synchronized(this)
{
// send data to usb device
byte[] bytes = data.getBytes();
sentBytes = connection.bulkTransfer(output, bytes, bytes.length, 1000);
}
}
return Integer.toString(sentBytes);
}
public String read()
{
// reinitialize read value byte array
Arrays.fill(readBytes, (byte) 0);
// wait for some data from the mcu
int recvBytes = connection.bulkTransfer(input, readBytes, readBytes.length, 3000);
if(recvBytes > 0)
{
Log.d("trebla", "Got some data: " + new String(readBytes));
}
else
{
Log.d("trebla", "Did not get any data: " + recvBytes);
}
return Integer.toString(recvBytes);
}
public String listUsbDevices()
{
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
if(deviceList.size() == 0)
{
return "no usb devices found";
}
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
String returnValue = "";
UsbInterface usbInterface;
while(deviceIterator.hasNext())
{
UsbDevice device = deviceIterator.next();
returnValue += "Name: " + device.getDeviceName();
returnValue += "\nID: " + device.getDeviceId();
returnValue += "\nProtocol: " + device.getDeviceProtocol();
returnValue += "\nClass: " + device.getDeviceClass();
returnValue += "\nSubclass: " + device.getDeviceSubclass();
returnValue += "\nProduct ID: " + device.getProductId();
returnValue += "\nVendor ID: " + device.getVendorId();
returnValue += "\nInterface count: " + device.getInterfaceCount();
for(int i = 0; i < device.getInterfaceCount(); i++)
{
usbInterface = device.getInterface(i);
returnValue += "\n Interface " + i;
returnValue += "\n\tInterface ID: " + usbInterface.getId();
returnValue += "\n\tClass: " + usbInterface.getInterfaceClass();
returnValue += "\n\tProtocol: " + usbInterface.getInterfaceProtocol();
returnValue += "\n\tSubclass: " + usbInterface.getInterfaceSubclass();
returnValue += "\n\tEndpoint count: " + usbInterface.getEndpointCount();
for(int j = 0; j < usbInterface.getEndpointCount(); j++)
{
returnValue += "\n\t Endpoint " + j;
returnValue += "\n\t\tAddress: " + usbInterface.getEndpoint(j).getAddress();
returnValue += "\n\t\tAttributes: " + usbInterface.getEndpoint(j).getAttributes();
returnValue += "\n\t\tDirection: " + usbInterface.getEndpoint(j).getDirection();
returnValue += "\n\t\tNumber: " + usbInterface.getEndpoint(j).getEndpointNumber();
returnValue += "\n\t\tInterval: " + usbInterface.getEndpoint(j).getInterval();
returnValue += "\n\t\tType: " + usbInterface.getEndpoint(j).getType();
returnValue += "\n\t\tMax packet size: " + usbInterface.getEndpoint(j).getMaxPacketSize();
}
}
}
return returnValue;
}
private void setupConnection()
{
// find the right interface
for(int i = 0; i < usbDevice.getInterfaceCount(); i++)
{
// communications device class (CDC) type device
if(usbDevice.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)
{
intf = usbDevice.getInterface(i);
// find the endpoints
for(int j = 0; j < intf.getEndpointCount(); j++)
{
if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
{
// from android to device
output = intf.getEndpoint(j);
}
if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
{
// from device to android
input = intf.getEndpoint(j);
}
}
}
}
}
private final BroadcastReceiver usbReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if(ACTION_USB_PERMISSION.equals(action))
{
// broadcast is like an interrupt and works asynchronously with the class, it must be synced just in case
synchronized(this)
{
if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
setupConnection();
connection = usbManager.openDevice(usbDevice);
connection.claimInterface(intf, true);
// set flow control to 8N1 at 9600 baud
int baudRate = 9600;
byte stopBitsByte = 1;
byte parityBitesByte = 0;
byte dataBits = 8;
byte[] msg = {
(byte) (baudRate & 0xff),
(byte) ((baudRate >> 8) & 0xff),
(byte) ((baudRate >> 16) & 0xff),
(byte) ((baudRate >> 24) & 0xff),
stopBitsByte,
parityBitesByte,
(byte) dataBits
};
connection.controlTransfer(UsbConstants.USB_TYPE_CLASS | 0x01, 0x20, 0, 0, msg, msg.length, 5000);
}
else
{
Log.d("trebla", "Permission denied for USB device");
}
}
}
else if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))
{
Log.d("trebla", "USB device detached");
}
}
};
}
I keep getting -1 from the read() method which indicates some kind of error, it always times out. Maybe the problem comes from the connection configuration, I've tried several (read: trial and error) and none worked, surprisingly I don't need any configuration to send data to the device.
Edit
It must also be noted that the cable I'm using is micro-USB to micro-USB and it only works in one way, that is my device is powered by my phone only when the plug A connected to phone and plug B connected to device, not the other way around... it seems very strange. The fact that I'm able to send data and not receive when plugged the right way remains.
EDIT 2
I found that somebody else had the same problem but it seems he wasn't able to solve it.
EDIT 3
I finally found the solution on this page:
Another major oversight is that there is no mechanism for the host to notify the device that there is a data sink on the host side ready to accept data. This means that the device may try to send data while the host isn't listening, causing lengthy blocking timeouts in the transmission routines. It is thus highly recommended that the virtual serial line DTR (Data Terminal Ready) signal be used where possible to determine if a host application is ready for data.
So the DTR signal was mandatory and all I had to do was to add this to the interface configuration:
connection.controlTransfer(0x21, 0x22, 0x1, 0, null, 0, 0);
EDIT 4
If anybody is interested I finished the project and it's open source and published on my GitHub account. It's not stable all the time though (see the notes) and I don't plan working on it anymore, but it works. Feel free to use it for your own projects.
You can use UsbSerial Lib of from https://github.com/mik3y/usb-serial-for-android
My example code:
UsbManager usbManager = null;
UsbDeviceConnection connection = null;
UsbSerialDriver driver = null;
UsbSerialPort port = null;
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
// Open a connection to the first available driver.
for (UsbSerialDriver usd : availableDrivers) {
UsbDevice udv = usd.getDevice();
if (udv.getVendorId()==0x067B || udv.getProductId()==2303){
driver = usd;
break;
}
}
connection = usbManager.openDevice(driver.getDevice());
port = driver.getPorts().get(0);
driver.getDevice().
}
if (connection == null) return;
try{
port.open(connection);
port.setParameters(4800, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
try{
byte buffer[] = new byte[250];
//Log.d("GPS_REQ", "->");
int numBytesRead = port.read(buffer, 500); //5000;
}catch (Exception e) {
Log.d("GPS_ERR", e.getLocalizedMessage());
}

Serial to USB Android application with health device

I am creating an Android application to let communicate my Galaxy Tablet with an health device, via serial to USB connection.
The code I implemented does not work! neither the OUT nor IN communication starts
Does someone has any idea?
public void recordData(View _view){
text = (TextView)findViewById(R.id.textView1);
manager=(UsbManager) getSystemService(Context.USB_SERVICE);
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
manager.requestPermission(device, mPermissionIntent);
text.setText(text.getText()+"\n"+device.getDeviceName());
}
}
private UsbManager manager=null;
private boolean forceClaim = true;
private UsbDeviceConnection connection;
private UsbEndpoint input = null,output=null;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
isRecording=true;
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
//call method to set up device communication
UsbInterface intf = device.getInterface(0);
connection = manager.openDevice(device);
connection.claimInterface(intf, forceClaim);
//connection settings
int op= connection.controlTransfer(0x40, 0, 0, 0, null, 0, 0);// reset //0x40
int op2= connection.controlTransfer(0x40, 0, 1, 0, null, 0, 0);//clear Rx
int op3= connection.controlTransfer(0x40, 0, 2, 0, null, 0, 0);// clear Tx
int op3b= connection.controlTransfer(0x40, 0x02, 0x0000, 0, null, 0, 0);//control flow
int op4= connection.controlTransfer(0x40, 0x03, 0x001A, 0, null, 0, 0);// baud rate 115200
int op5= connection.controlTransfer(0x40, 0x04, 0x0008, 0, null, 0, 0);//8 bit
int endPts = intf.getEndpointCount();
for(int e = 0; e < endPts; e++){
UsbEndpoint endpoint = intf.getEndpoint(e);
endpoint.getAttributes();
if( endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK){
if(endpoint.getDirection() == UsbConstants.USB_DIR_IN){
input = endpoint;
Log.d("Endpoint", "Got input");
}else if(endpoint.getDirection() == UsbConstants.USB_DIR_OUT){
output = endpoint;
Log.d("Endpoint", "Got output");
}
}
}
text.setText(text.getText()+"\nOut= "+String.valueOf(output.getEndpointNumber()));
text.setText(text.getText()+"\nIn= "+String.valueOf(input.getEndpointNumber()));
byte [] buffer = {77}; // M\n in ascii
for (int i = 0; i < buffer.length; ++i)
{
connection.bulkTransfer(output, new byte[] {buffer[i]}, 1, 0);
}
read();
}
}
else {
//error
}
}
}
}
};
//read thread
private void read() {
Runnable r = new Runnable() {
byte[] buffer = new byte[64];
byte[] buffer2;
public void run() {
while (isRecording) {
{
int op = connection.bulkTransfer(input, buffer, 64, 0);
if (op > 2) {
buffer2 = new byte[op];
for (int i = 0; i < op - 2; ++i) {
buffer2[i] = buffer[i+2];
text.setText(text.getText()+"\n"+String.valueOf(buffer2[i]));
}
}
}
}
}
};
Thread t = new Thread(r);
t.start();
Thank you very much!
Before trying to send the bytes you have to control the transaction first:
Use:
// for writing to USB with 9600 baudrate
connection.controlTransfer(0x00000000, 0x03, 0x4138, 0, null, 0, 0);
and
// for reading from USB with 9600 baudrate
connection.controlTransfer(0x00000080, 0x03, 0x4138, 0, null, 0, 0);
Reference:
http://developer.android.com/guide/topics/connectivity/usb/host.html
http://developer.android.com/reference/android/hardware/usb/UsbConstants.html

Unsuccessful bulkTransfer - Android 4.0.3

I want to send a short data package (just 2 characters) via bulkTransfer to a camera connected via USB. I am using Samsung Galaxy S2 with Android 4.0.3 as a host. Everything seems fine, accept... no data is actually being sent. Theoretically, the method bulkTransfer returns a positive value, meaning the data has been transfered, but there is no visible effect. The code is as follows:
char ch = (char)34;
char[] record = {'P',ch};
String r = record.toString();
byte[] bytes = r.getBytes(Charset.forName("ASCII"));
int TIMEOUT = 10000;
boolean forceClaim = true;
UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbInterface intf = device.getInterface(0);
for (int i = 0; i < intf.getEndpointCount(); i++) {
UsbEndpoint ep = intf.getEndpoint(i);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
endpoint = ep;
//Integer dir = endpoint.getDirection();
UsbDeviceConnection connection = mUsbManager.openDevice(device);
if(connection!=null){devMessage+=" I connected";}
connection.claimInterface(intf, forceClaim);
Integer res = connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
if (res>0){devMessage += "some data transfered.";}
connection.releaseInterface(intf);
break;
}
}
Is there anything more I need to include before I start bulkTransfer? Is there any need for controlTransfer before I start bulkTransfer? Is there anything else I might be forgetting.
Please be understanding as this is my first app with USB communication and there are not many resources on the net. I've already read everything about usb host on developer.android... so please do not direct me there. Thanks a lot for any help.
May be the interface is not right Your using the device.getInterface(0). So this may not be right. Try this to get the interface.
for (int i = 0; i < device.getInterfaceCount(); i++) {
UsbInterface usbif = device.getInterface(i);
UsbEndpoint tOut = null;
UsbEndpoint tIn = null;
int tEndpointCnt = usbif.getEndpointCount();
if (tEndpointCnt >= 2) {
for (int j = 0; j < tEndpointCnt; j++) {
if (usbif.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT) {
tOut = usbif.getEndpoint(j);
} else if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN) {
tIn = usbif.getEndpoint(j);
}
}
}
if (tOut != null && tIn != null) {
// This interface have both USB_DIR_OUT
// and USB_DIR_IN of USB_ENDPOINT_XFER_BULK
usbInterface = usbif;
endpointOut = tOut;
endpointIn = tIn;
}
}
}

Categories

Resources