mirror of
https://github.com/mik3y/usb-serial-for-android
synced 2025-06-09 00:46:11 +00:00
API refactor, adding UsbSerialPort interface.
- UsbSerialDriver is now a discrete interface. - UsbSerialDriver provides getPorts() method, returning one or more usable UsbSerialPort. - Use of UsbDeviceConnection is deferred until open(), making it possible to probe for ports without permission from Android. (Thanks to Felix for inspiring some of these changes).
This commit is contained in:
parent
d9db4e3607
commit
8abc3be1f1
@ -1,4 +1,5 @@
|
||||
/* Copyright 2011 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,7 +16,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.examples;
|
||||
@ -41,6 +42,7 @@ import android.widget.TextView;
|
||||
import android.widget.TwoLineListItem;
|
||||
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialProber;
|
||||
import com.hoho.android.usbserial.util.HexDump;
|
||||
|
||||
@ -80,19 +82,8 @@ public class DeviceListActivity extends Activity {
|
||||
|
||||
};
|
||||
|
||||
/** Simple container for a UsbDevice and its driver. */
|
||||
private static class DeviceEntry {
|
||||
public UsbDevice device;
|
||||
public UsbSerialDriver driver;
|
||||
|
||||
DeviceEntry(UsbDevice device, UsbSerialDriver driver) {
|
||||
this.device = device;
|
||||
this.driver = driver;
|
||||
}
|
||||
}
|
||||
|
||||
private List<DeviceEntry> mEntries = new ArrayList<DeviceEntry>();
|
||||
private ArrayAdapter<DeviceEntry> mAdapter;
|
||||
private List<UsbSerialPort> mEntries = new ArrayList<UsbSerialPort>();
|
||||
private ArrayAdapter<UsbSerialPort> mAdapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@ -104,7 +95,8 @@ public class DeviceListActivity extends Activity {
|
||||
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||
mProgressBarTitle = (TextView) findViewById(R.id.progressBarTitle);
|
||||
|
||||
mAdapter = new ArrayAdapter<DeviceEntry>(this, android.R.layout.simple_expandable_list_item_2, mEntries) {
|
||||
mAdapter = new ArrayAdapter<UsbSerialPort>(this,
|
||||
android.R.layout.simple_expandable_list_item_2, mEntries) {
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
final TwoLineListItem row;
|
||||
@ -116,14 +108,16 @@ public class DeviceListActivity extends Activity {
|
||||
row = (TwoLineListItem) convertView;
|
||||
}
|
||||
|
||||
final DeviceEntry entry = mEntries.get(position);
|
||||
final UsbSerialPort port = mEntries.get(position);
|
||||
final UsbSerialDriver driver = port.getDriver();
|
||||
final UsbDevice device = driver.getDevice();
|
||||
|
||||
final String title = String.format("Vendor %s Product %s",
|
||||
HexDump.toHexString((short) entry.device.getVendorId()),
|
||||
HexDump.toHexString((short) entry.device.getProductId()));
|
||||
HexDump.toHexString((short) device.getVendorId()),
|
||||
HexDump.toHexString((short) device.getProductId()));
|
||||
row.getText1().setText(title);
|
||||
|
||||
final String subtitle = entry.driver != null ?
|
||||
entry.driver.getClass().getSimpleName() : "No Driver";
|
||||
final String subtitle = driver.getClass().getSimpleName();
|
||||
row.getText2().setText(subtitle);
|
||||
|
||||
return row;
|
||||
@ -141,14 +135,8 @@ public class DeviceListActivity extends Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
final DeviceEntry entry = mEntries.get(position);
|
||||
final UsbSerialDriver driver = entry.driver;
|
||||
if (driver == null) {
|
||||
Log.d(TAG, "No driver.");
|
||||
return;
|
||||
}
|
||||
|
||||
showConsoleActivity(driver);
|
||||
final UsbSerialPort port = mEntries.get(position);
|
||||
showConsoleActivity(port);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -168,31 +156,28 @@ public class DeviceListActivity extends Activity {
|
||||
private void refreshDeviceList() {
|
||||
showProgressBar();
|
||||
|
||||
new AsyncTask<Void, Void, List<DeviceEntry>>() {
|
||||
new AsyncTask<Void, Void, List<UsbSerialPort>>() {
|
||||
@Override
|
||||
protected List<DeviceEntry> doInBackground(Void... params) {
|
||||
protected List<UsbSerialPort> doInBackground(Void... params) {
|
||||
Log.d(TAG, "Refreshing device list ...");
|
||||
SystemClock.sleep(1000);
|
||||
final List<DeviceEntry> result = new ArrayList<DeviceEntry>();
|
||||
for (final UsbDevice device : mUsbManager.getDeviceList().values()) {
|
||||
|
||||
final List<UsbSerialDriver> drivers =
|
||||
UsbSerialProber.probeSingleDevice(mUsbManager, device);
|
||||
Log.d(TAG, "Found usb device: " + device);
|
||||
if (drivers.isEmpty()) {
|
||||
Log.d(TAG, " - No UsbSerialDriver available.");
|
||||
result.add(new DeviceEntry(device, null));
|
||||
} else {
|
||||
for (UsbSerialDriver driver : drivers) {
|
||||
Log.d(TAG, " + " + driver);
|
||||
result.add(new DeviceEntry(device, driver));
|
||||
}
|
||||
}
|
||||
UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager);
|
||||
|
||||
final List<UsbSerialPort> result = new ArrayList<UsbSerialPort>();
|
||||
for (final UsbSerialDriver driver : drivers) {
|
||||
final List<UsbSerialPort> ports = driver.getPorts();
|
||||
Log.d(TAG, String.format("+ %s: %s port%s",
|
||||
driver, Integer.valueOf(ports.size()), ports.size() == 1 ? "" : "s"));
|
||||
result.addAll(ports);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<DeviceEntry> result) {
|
||||
protected void onPostExecute(List<UsbSerialPort> result) {
|
||||
mEntries.clear();
|
||||
mEntries.addAll(result);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
@ -214,8 +199,8 @@ public class DeviceListActivity extends Activity {
|
||||
mProgressBar.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
private void showConsoleActivity(UsbSerialDriver driver) {
|
||||
SerialConsoleActivity.show(this, driver);
|
||||
private void showConsoleActivity(UsbSerialPort port) {
|
||||
SerialConsoleActivity.show(this, port);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright 2011 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,7 +16,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.examples;
|
||||
@ -23,12 +24,14 @@ package com.hoho.android.usbserial.examples;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
import com.hoho.android.usbserial.util.HexDump;
|
||||
import com.hoho.android.usbserial.util.SerialInputOutputManager;
|
||||
|
||||
@ -37,7 +40,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Monitors a single {@link UsbSerialDriver} instance, showing all data
|
||||
* Monitors a single {@link UsbSerialPort} instance, showing all data
|
||||
* received.
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
@ -48,7 +51,7 @@ public class SerialConsoleActivity extends Activity {
|
||||
|
||||
/**
|
||||
* Driver instance, passed in statically via
|
||||
* {@link #show(Context, UsbSerialDriver)}.
|
||||
* {@link #show(Context, UsbSerialPort)}.
|
||||
*
|
||||
* <p/>
|
||||
* This is a devious hack; it'd be cleaner to re-create the driver using
|
||||
@ -56,7 +59,7 @@ public class SerialConsoleActivity extends Activity {
|
||||
* can get away with it because both activities will run in the same
|
||||
* process, and this is a simple demo.
|
||||
*/
|
||||
private static UsbSerialDriver sDriver = null;
|
||||
private static UsbSerialPort sPort = null;
|
||||
|
||||
private TextView mTitleTextView;
|
||||
private TextView mDumpTextView;
|
||||
@ -98,13 +101,13 @@ public class SerialConsoleActivity extends Activity {
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
stopIoManager();
|
||||
if (sDriver != null) {
|
||||
if (sPort != null) {
|
||||
try {
|
||||
sDriver.close();
|
||||
sPort.close();
|
||||
} catch (IOException e) {
|
||||
// Ignore.
|
||||
}
|
||||
sDriver = null;
|
||||
sPort = null;
|
||||
}
|
||||
finish();
|
||||
}
|
||||
@ -112,25 +115,33 @@ public class SerialConsoleActivity extends Activity {
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "Resumed, sDriver=" + sDriver);
|
||||
if (sDriver == null) {
|
||||
Log.d(TAG, "Resumed, port=" + sPort);
|
||||
if (sPort == null) {
|
||||
mTitleTextView.setText("No serial device.");
|
||||
} else {
|
||||
final UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
||||
|
||||
UsbDeviceConnection connection = usbManager.openDevice(sPort.getDriver().getDevice());
|
||||
if (connection == null) {
|
||||
mTitleTextView.setText("Opening device failed");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sDriver.open();
|
||||
sDriver.setParameters(115200, 8, UsbSerialDriver.STOPBITS_1, UsbSerialDriver.PARITY_NONE);
|
||||
sPort.open(connection);
|
||||
sPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error setting up device: " + e.getMessage(), e);
|
||||
mTitleTextView.setText("Error opening device: " + e.getMessage());
|
||||
try {
|
||||
sDriver.close();
|
||||
sPort.close();
|
||||
} catch (IOException e2) {
|
||||
// Ignore.
|
||||
}
|
||||
sDriver = null;
|
||||
sPort = null;
|
||||
return;
|
||||
}
|
||||
mTitleTextView.setText("Serial device: " + sDriver.getClass().getSimpleName());
|
||||
mTitleTextView.setText("Serial device: " + sPort.getClass().getSimpleName());
|
||||
}
|
||||
onDeviceStateChange();
|
||||
}
|
||||
@ -144,9 +155,9 @@ public class SerialConsoleActivity extends Activity {
|
||||
}
|
||||
|
||||
private void startIoManager() {
|
||||
if (sDriver != null) {
|
||||
if (sPort != null) {
|
||||
Log.i(TAG, "Starting io manager ..");
|
||||
mSerialIoManager = new SerialInputOutputManager(sDriver, mListener);
|
||||
mSerialIoManager = new SerialInputOutputManager(sPort, mListener);
|
||||
mExecutor.submit(mSerialIoManager);
|
||||
}
|
||||
}
|
||||
@ -169,8 +180,8 @@ public class SerialConsoleActivity extends Activity {
|
||||
* @param context
|
||||
* @param driver
|
||||
*/
|
||||
static void show(Context context, UsbSerialDriver driver) {
|
||||
sDriver = driver;
|
||||
static void show(Context context, UsbSerialPort port) {
|
||||
sPort = port;
|
||||
final Intent intent = new Intent(context, SerialConsoleActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
context.startActivity(intent);
|
||||
|
@ -1,3 +1,24 @@
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
import android.hardware.usb.UsbConstants;
|
||||
@ -8,7 +29,9 @@ import android.hardware.usb.UsbInterface;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -19,10 +42,30 @@ import java.util.Map;
|
||||
* href="http://www.usb.org/developers/devclass_docs/usbcdc11.pdf">Universal
|
||||
* Serial Bus Class Definitions for Communication Devices, v1.1</a>
|
||||
*/
|
||||
public class CdcAcmSerialDriver extends CommonUsbSerialDriver {
|
||||
public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private final String TAG = CdcAcmSerialDriver.class.getSimpleName();
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
|
||||
public CdcAcmSerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new CdcAdcmSerialPort(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
}
|
||||
|
||||
class CdcAdcmSerialPort extends CommonUsbSerialPort {
|
||||
|
||||
private UsbInterface mControlInterface;
|
||||
private UsbInterface mDataInterface;
|
||||
|
||||
@ -41,15 +84,25 @@ public class CdcAcmSerialDriver extends CommonUsbSerialDriver {
|
||||
private static final int SET_CONTROL_LINE_STATE = 0x22;
|
||||
private static final int SEND_BREAK = 0x23;
|
||||
|
||||
public CdcAcmSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
|
||||
super(device, connection);
|
||||
public CdcAdcmSerialPort(UsbDevice device) {
|
||||
super(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() throws IOException {
|
||||
Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
|
||||
public UsbSerialDriver getDriver() {
|
||||
return CdcAcmSerialDriver.this;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Claiming control interface.");
|
||||
@Override
|
||||
public void open(UsbDeviceConnection connection) throws IOException {
|
||||
if (mConnection != null) {
|
||||
throw new IOException("Already open");
|
||||
}
|
||||
|
||||
mConnection = connection;
|
||||
boolean opened = false;
|
||||
try {
|
||||
Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
|
||||
mControlInterface = mDevice.getInterface(0);
|
||||
Log.d(TAG, "Control iface=" + mControlInterface);
|
||||
// class should be USB_CLASS_COMM
|
||||
@ -72,6 +125,12 @@ public class CdcAcmSerialDriver extends CommonUsbSerialDriver {
|
||||
Log.d(TAG, "Read endpoint direction: " + mReadEndpoint.getDirection());
|
||||
mWriteEndpoint = mDataInterface.getEndpoint(0);
|
||||
Log.d(TAG, "Write endpoint direction: " + mWriteEndpoint.getDirection());
|
||||
opened = true;
|
||||
} finally {
|
||||
if (!opened) {
|
||||
mConnection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int sendAcmControlMessage(int request, int value, byte[] buf) {
|
||||
@ -81,7 +140,11 @@ public class CdcAcmSerialDriver extends CommonUsbSerialDriver {
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (mConnection == null) {
|
||||
throw new IOException("Already closed");
|
||||
}
|
||||
mConnection.close();
|
||||
mConnection = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -216,6 +279,8 @@ public class CdcAcmSerialDriver extends CommonUsbSerialDriver {
|
||||
sendAcmControlMessage(SET_CONTROL_LINE_STATE, value, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<Integer, int[]>();
|
||||
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_ARDUINO),
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright 2013 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,7 +16,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
@ -30,13 +31,15 @@ import java.io.IOException;
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
*/
|
||||
abstract class CommonUsbSerialDriver implements UsbSerialDriver {
|
||||
abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||
|
||||
public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
|
||||
public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
|
||||
|
||||
protected final UsbDevice mDevice;
|
||||
protected final UsbDeviceConnection mConnection;
|
||||
|
||||
// non-null when open()
|
||||
protected UsbDeviceConnection mConnection = null;
|
||||
|
||||
protected final Object mReadBufferLock = new Object();
|
||||
protected final Object mWriteBufferLock = new Object();
|
||||
@ -47,9 +50,8 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver {
|
||||
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
|
||||
protected byte[] mWriteBuffer;
|
||||
|
||||
public CommonUsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
|
||||
public CommonUsbSerialPort(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mConnection = connection;
|
||||
|
||||
mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE];
|
||||
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
|
||||
@ -95,7 +97,7 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void open() throws IOException;
|
||||
public abstract void open(UsbDeviceConnection connection) throws IOException;
|
||||
|
||||
@Override
|
||||
public abstract void close() throws IOException;
|
@ -1,8 +1,25 @@
|
||||
package com.hoho.android.usbserial.driver;
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
import android.hardware.usb.UsbConstants;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
@ -11,9 +28,36 @@ import android.hardware.usb.UsbEndpoint;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.util.Log;
|
||||
|
||||
public class Cp2102SerialDriver extends CommonUsbSerialDriver {
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Cp2102SerialDriver implements UsbSerialDriver {
|
||||
|
||||
private static final String TAG = Cp2102SerialDriver.class.getSimpleName();
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
|
||||
public Cp2102SerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new Cp2102SerialPort(mDevice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
}
|
||||
|
||||
class Cp2102SerialPort extends CommonUsbSerialPort {
|
||||
|
||||
private static final int DEFAULT_BAUD_RATE = 9600;
|
||||
|
||||
private static final int USB_WRITE_TIMEOUT_MILLIS = 5000;
|
||||
@ -60,8 +104,13 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver {
|
||||
private UsbEndpoint mReadEndpoint;
|
||||
private UsbEndpoint mWriteEndpoint;
|
||||
|
||||
public Cp2102SerialDriver(UsbDevice device, UsbDeviceConnection connection) {
|
||||
super(device, connection);
|
||||
public Cp2102SerialPort(UsbDevice device) {
|
||||
super(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbSerialDriver getDriver() {
|
||||
return Cp2102SerialDriver.this;
|
||||
}
|
||||
|
||||
private int setConfigSingle(int request, int value) {
|
||||
@ -70,7 +119,12 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() throws IOException {
|
||||
public void open(UsbDeviceConnection connection) throws IOException {
|
||||
if (mConnection != null) {
|
||||
throw new IOException("Already opened.");
|
||||
}
|
||||
|
||||
mConnection = connection;
|
||||
boolean opened = false;
|
||||
try {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||
@ -97,19 +151,30 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver {
|
||||
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_ENABLE);
|
||||
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, MCR_ALL | CONTROL_WRITE_DTR | CONTROL_WRITE_RTS);
|
||||
setConfigSingle(SILABSER_SET_BAUDDIV_REQUEST_CODE, BAUD_RATE_GEN_FREQ / DEFAULT_BAUD_RATE);
|
||||
// setParameters(DEFAULT_BAUD_RATE, DEFAULT_DATA_BITS, DEFAULT_STOP_BITS, DEFAULT_PARITY);
|
||||
// setParameters(DEFAULT_BAUD_RATE, DEFAULT_DATA_BITS, DEFAULT_STOP_BITS, DEFAULT_PARITY);
|
||||
opened = true;
|
||||
} finally {
|
||||
if (!opened) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException e) {
|
||||
// Ignore IOExceptions during close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (mConnection == null) {
|
||||
throw new IOException("Already closed");
|
||||
}
|
||||
try {
|
||||
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_DISABLE);
|
||||
mConnection.close();
|
||||
} finally {
|
||||
mConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -261,6 +326,10 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRTS(boolean value) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean purgeHwBuffers(boolean purgeReadBuffers,
|
||||
boolean purgeWriteBuffers) throws IOException {
|
||||
@ -274,8 +343,6 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRTS(boolean value) throws IOException {
|
||||
}
|
||||
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
@ -287,5 +354,4 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver {
|
||||
return supportedDevices;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright 2011 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,7 +16,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
@ -31,14 +32,16 @@ import com.hoho.android.usbserial.util.HexDump;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A {@link CommonUsbSerialDriver} implementation for a variety of FTDI devices
|
||||
* A {@link CommonUsbSerialPort} implementation for a variety of FTDI devices
|
||||
* <p>
|
||||
* This driver is based on
|
||||
* <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is
|
||||
* This driver is based on <a
|
||||
* href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is
|
||||
* copyright and subject to the following terms:
|
||||
*
|
||||
* <pre>
|
||||
@ -58,9 +61,11 @@ import java.util.Map;
|
||||
* unsupported devices. Devices listed as "supported" support the following
|
||||
* features:
|
||||
* <ul>
|
||||
* <li>Read and write of serial data (see {@link #read(byte[], int)} and
|
||||
* {@link #write(byte[], int)}.
|
||||
* <li>Setting baud rate (see {@link #setBaudRate(int)}).
|
||||
* <li>Read and write of serial data (see
|
||||
* {@link CommonUsbSerialPort#read(byte[], int)} and
|
||||
* {@link CommonUsbSerialPort#write(byte[], int)}.</li>
|
||||
* <li>Setting serial line parameters (see
|
||||
* {@link CommonUsbSerialPort#setParameters(int, int, int, int)}.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>
|
||||
@ -82,17 +87,43 @@ import java.util.Map;
|
||||
* </p>
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
* @see <a href="http://code.google.com/p/usb-serial-for-android/">USB Serial
|
||||
* @see <a href="https://github.com/mik3y/usb-serial-for-android">USB Serial
|
||||
* for Android project page</a>
|
||||
* @see <a href="http://www.ftdichip.com/">FTDI Homepage</a>
|
||||
* @see <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>
|
||||
*/
|
||||
public class FtdiSerialDriver extends CommonUsbSerialDriver {
|
||||
public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
|
||||
/**
|
||||
* FTDI chip types.
|
||||
*/
|
||||
private static enum DeviceType {
|
||||
TYPE_BM, TYPE_AM, TYPE_2232C, TYPE_R, TYPE_2232H, TYPE_4232H;
|
||||
}
|
||||
|
||||
public FtdiSerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new FtdiSerialPort(mDevice);
|
||||
}
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
}
|
||||
|
||||
private class FtdiSerialPort extends CommonUsbSerialPort {
|
||||
|
||||
public static final int USB_TYPE_STANDARD = 0x00 << 5;
|
||||
public static final int USB_TYPE_CLASS = 0x01 << 5;
|
||||
public static final int USB_TYPE_VENDOR = 0x02 << 5;
|
||||
public static final int USB_TYPE_RESERVED = 0x03 << 5;
|
||||
public static final int USB_TYPE_CLASS = 0x00 << 5;
|
||||
public static final int USB_TYPE_VENDOR = 0x00 << 5;
|
||||
public static final int USB_TYPE_RESERVED = 0x00 << 5;
|
||||
|
||||
public static final int USB_RECIP_DEVICE = 0x00;
|
||||
public static final int USB_RECIP_INTERFACE = 0x01;
|
||||
@ -150,13 +181,6 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
|
||||
|
||||
private DeviceType mType;
|
||||
|
||||
/**
|
||||
* FTDI chip types.
|
||||
*/
|
||||
private static enum DeviceType {
|
||||
TYPE_BM, TYPE_AM, TYPE_2232C, TYPE_R, TYPE_2232H, TYPE_4232H;
|
||||
}
|
||||
|
||||
private int mInterface = 0; /* INTERFACE_ANY */
|
||||
|
||||
private int mMaxPacketSize = 64; // TODO(mikey): detect
|
||||
@ -168,6 +192,15 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
|
||||
*/
|
||||
private static final boolean ENABLE_ASYNC_READS = false;
|
||||
|
||||
public FtdiSerialPort(UsbDevice device) {
|
||||
super(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbSerialDriver getDriver() {
|
||||
return FtdiSerialDriver.this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter FTDI status bytes from buffer
|
||||
* @param src The source buffer (which contains status bytes)
|
||||
@ -194,19 +227,6 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
|
||||
return totalBytesRead - (packetsCount * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param usbDevice the {@link UsbDevice} to use
|
||||
* @param usbConnection the {@link UsbDeviceConnection} to use
|
||||
* @throws UsbSerialRuntimeException if the given device is incompatible
|
||||
* with this driver
|
||||
*/
|
||||
public FtdiSerialDriver(UsbDevice usbDevice, UsbDeviceConnection usbConnection) {
|
||||
super(usbDevice, usbConnection);
|
||||
mType = null;
|
||||
}
|
||||
|
||||
public void reset() throws IOException {
|
||||
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,
|
||||
SIO_RESET_SIO, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
@ -219,7 +239,10 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() throws IOException {
|
||||
public void open(UsbDeviceConnection connection) throws IOException {
|
||||
if (mConnection != null) {
|
||||
throw new IOException("Already open");
|
||||
}
|
||||
boolean opened = false;
|
||||
try {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||
@ -234,13 +257,22 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
|
||||
} finally {
|
||||
if (!opened) {
|
||||
close();
|
||||
} else {
|
||||
mConnection = connection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
public void close() throws IOException {
|
||||
if (mConnection == null) {
|
||||
throw new IOException("Already closed");
|
||||
}
|
||||
try {
|
||||
mConnection.close();
|
||||
} finally {
|
||||
mConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -531,9 +563,9 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
|
||||
throw new IOException("Flushing RX failed: result=" + result);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<Integer, int[]>();
|
||||
|
@ -0,0 +1,108 @@
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Maps (vendor id, product id) pairs to the corresponding serial driver.
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
*/
|
||||
public class ProbeTable {
|
||||
|
||||
private final Map<Pair<Integer, Integer>, Class<? extends UsbSerialDriver>> mProbeTable =
|
||||
new LinkedHashMap<Pair<Integer,Integer>, Class<? extends UsbSerialDriver>>();
|
||||
|
||||
/**
|
||||
* Adds or updates a (vendor, product) pair in the table.
|
||||
*
|
||||
* @param vendorId the USB vendor id
|
||||
* @param productId the USB product id
|
||||
* @param driverClass the driver class responsible for this pair
|
||||
* @return {@code this}, for chaining
|
||||
*/
|
||||
public ProbeTable addProduct(int vendorId, int productId,
|
||||
Class<? extends UsbSerialDriver> driverClass) {
|
||||
mProbeTable.put(Pair.create(vendorId, productId), driverClass);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to add all supported products from
|
||||
* {@code getSupportedProducts} static method.
|
||||
*
|
||||
* @param driverClass
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
ProbeTable addDriver(Class<? extends UsbSerialDriver> driverClass) {
|
||||
final Method method;
|
||||
|
||||
try {
|
||||
method = driverClass.getMethod("getSupportedDevices");
|
||||
} catch (SecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
final Map<Integer, int[]> devices;
|
||||
try {
|
||||
devices = (Map<Integer, int[]>) method.invoke(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
for (Map.Entry<Integer, int[]> entry : devices.entrySet()) {
|
||||
final int vendorId = entry.getKey().intValue();
|
||||
for (int productId : entry.getValue()) {
|
||||
addProduct(vendorId, productId, driverClass);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the driver for the given (vendor, product) pair, or {@code null}
|
||||
* if no match.
|
||||
*
|
||||
* @param vendorId the USB vendor id
|
||||
* @param productId the USB product id
|
||||
* @return the driver class matching this pair, or {@code null}
|
||||
*/
|
||||
public Class<? extends UsbSerialDriver> findDriver(int vendorId, int productId) {
|
||||
final Pair<Integer, Integer> pair = Pair.create(vendorId, productId);
|
||||
return mProbeTable.get(pair);
|
||||
}
|
||||
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -36,10 +36,35 @@ import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
public class ProlificSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private final String TAG = ProlificSerialDriver.class.getSimpleName();
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
|
||||
public ProlificSerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new ProlificSerialPort(mDevice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
class ProlificSerialPort extends CommonUsbSerialPort {
|
||||
|
||||
private static final int USB_READ_TIMEOUT_MILLIS = 1000;
|
||||
private static final int USB_WRITE_TIMEOUT_MILLIS = 5000;
|
||||
|
||||
@ -98,7 +123,15 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
boolean mStopReadStatusThread = false;
|
||||
private IOException mReadStatusException = null;
|
||||
|
||||
private final String TAG = ProlificSerialDriver.class.getSimpleName();
|
||||
|
||||
public ProlificSerialPort(UsbDevice device) {
|
||||
super(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbSerialDriver getDriver() {
|
||||
return ProlificSerialDriver.this;
|
||||
}
|
||||
|
||||
private final byte[] inControlTransfer(int requestType, int request,
|
||||
int value, int index, int length) throws IOException {
|
||||
@ -137,6 +170,10 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
PROLIFIC_VENDOR_WRITE_REQUEST, value, index, data);
|
||||
}
|
||||
|
||||
private void resetDevice() throws IOException {
|
||||
purgeHwBuffers(true, true);
|
||||
}
|
||||
|
||||
private final void ctrlOut(int request, int value, int index, byte[] data)
|
||||
throws IOException {
|
||||
outControlTransfer(PROLIFIC_CTRL_OUT_REQTYPE, request, value, index,
|
||||
@ -157,10 +194,6 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
vendorOut(2, (mDeviceType == DEVICE_TYPE_HX) ? 0x44 : 0x24, null);
|
||||
}
|
||||
|
||||
private void resetDevice() throws IOException {
|
||||
purgeHwBuffers(true, true);
|
||||
}
|
||||
|
||||
private void setControlLines(int newControlLinesValue) throws IOException {
|
||||
ctrlOut(SET_CONTROL_REQUEST, newControlLinesValue, 0, null);
|
||||
mControlLinesValue = newControlLinesValue;
|
||||
@ -231,19 +264,20 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
return ((getStatus() & flag) == flag);
|
||||
}
|
||||
|
||||
public ProlificSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
|
||||
super(device, connection);
|
||||
@Override
|
||||
public void open(UsbDeviceConnection connection) throws IOException {
|
||||
if (mConnection != null) {
|
||||
throw new IOException("Already open");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() throws IOException {
|
||||
UsbInterface usbInterface = mDevice.getInterface(0);
|
||||
|
||||
if (!mConnection.claimInterface(usbInterface, true)) {
|
||||
if (!connection.claimInterface(usbInterface, true)) {
|
||||
throw new IOException("Error claiming Prolific interface 0");
|
||||
}
|
||||
|
||||
boolean openSuccessful = false;
|
||||
mConnection = connection;
|
||||
boolean opened = false;
|
||||
try {
|
||||
for (int i = 0; i < usbInterface.getEndpointCount(); ++i) {
|
||||
UsbEndpoint currentEndpoint = usbInterface.getEndpoint(i);
|
||||
@ -297,20 +331,20 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
resetDevice();
|
||||
|
||||
doBlackMagic();
|
||||
openSuccessful = true;
|
||||
opened = true;
|
||||
} finally {
|
||||
if (!openSuccessful) {
|
||||
try {
|
||||
mConnection.releaseInterface(usbInterface);
|
||||
} catch (Exception ingored) {
|
||||
// Do not cover possible exceptions
|
||||
}
|
||||
if (!opened) {
|
||||
mConnection = null;
|
||||
connection.releaseInterface(usbInterface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (mConnection == null) {
|
||||
throw new IOException("Already closed");
|
||||
}
|
||||
try {
|
||||
mStopReadStatusThread = true;
|
||||
synchronized (mReadStatusThreadLock) {
|
||||
@ -322,10 +356,13 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resetDevice();
|
||||
} finally {
|
||||
try {
|
||||
mConnection.releaseInterface(mDevice.getInterface(0));
|
||||
} finally {
|
||||
mConnection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,10 +457,6 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
lineRequestData[5] = 1;
|
||||
break;
|
||||
|
||||
case PARITY_EVEN:
|
||||
lineRequestData[5] = 2;
|
||||
break;
|
||||
|
||||
case PARITY_MARK:
|
||||
lineRequestData[5] = 3;
|
||||
break;
|
||||
@ -510,7 +543,8 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
|
||||
vendorOut(FLUSH_TX_REQUEST, 0, null);
|
||||
}
|
||||
|
||||
return true;
|
||||
return purgeReadBuffers || purgeWriteBuffers;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright 2012 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,8 +16,9 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright 2011 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,196 +16,33 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
import java.io.IOException;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Driver interface for a USB serial device.
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
*/
|
||||
public interface UsbSerialDriver {
|
||||
|
||||
/** 5 data bits. */
|
||||
public static final int DATABITS_5 = 5;
|
||||
|
||||
/** 6 data bits. */
|
||||
public static final int DATABITS_6 = 6;
|
||||
|
||||
/** 7 data bits. */
|
||||
public static final int DATABITS_7 = 7;
|
||||
|
||||
/** 8 data bits. */
|
||||
public static final int DATABITS_8 = 8;
|
||||
|
||||
/** No flow control. */
|
||||
public static final int FLOWCONTROL_NONE = 0;
|
||||
|
||||
/** RTS/CTS input flow control. */
|
||||
public static final int FLOWCONTROL_RTSCTS_IN = 1;
|
||||
|
||||
/** RTS/CTS output flow control. */
|
||||
public static final int FLOWCONTROL_RTSCTS_OUT = 2;
|
||||
|
||||
/** XON/XOFF input flow control. */
|
||||
public static final int FLOWCONTROL_XONXOFF_IN = 4;
|
||||
|
||||
/** XON/XOFF output flow control. */
|
||||
public static final int FLOWCONTROL_XONXOFF_OUT = 8;
|
||||
|
||||
/** No parity. */
|
||||
public static final int PARITY_NONE = 0;
|
||||
|
||||
/** Odd parity. */
|
||||
public static final int PARITY_ODD = 1;
|
||||
|
||||
/** Even parity. */
|
||||
public static final int PARITY_EVEN = 2;
|
||||
|
||||
/** Mark parity. */
|
||||
public static final int PARITY_MARK = 3;
|
||||
|
||||
/** Space parity. */
|
||||
public static final int PARITY_SPACE = 4;
|
||||
|
||||
/** 1 stop bit. */
|
||||
public static final int STOPBITS_1 = 1;
|
||||
|
||||
/** 1.5 stop bits. */
|
||||
public static final int STOPBITS_1_5 = 3;
|
||||
|
||||
/** 2 stop bits. */
|
||||
public static final int STOPBITS_2 = 2;
|
||||
|
||||
/**
|
||||
* Opens and initializes the device as a USB serial device. Upon success,
|
||||
* caller must ensure that {@link #close()} is eventually called.
|
||||
* Returns the raw {@link UsbDevice} backing this port.
|
||||
*
|
||||
* @throws IOException on error opening or initializing the device.
|
||||
* @return the device
|
||||
*/
|
||||
public void open() throws IOException;
|
||||
public UsbDevice getDevice();
|
||||
|
||||
/**
|
||||
* Closes the serial device.
|
||||
* Returns all available ports for this device. This list must have at least
|
||||
* one entry.
|
||||
*
|
||||
* @throws IOException on error closing the device.
|
||||
* @return the ports
|
||||
*/
|
||||
public void close() throws IOException;
|
||||
|
||||
/**
|
||||
* Reads as many bytes as possible into the destination buffer.
|
||||
*
|
||||
* @param dest the destination byte buffer
|
||||
* @param timeoutMillis the timeout for reading
|
||||
* @return the actual number of bytes read
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public int read(final byte[] dest, final int timeoutMillis) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes as many bytes as possible from the source buffer.
|
||||
*
|
||||
* @param src the source byte buffer
|
||||
* @param timeoutMillis the timeout for writing
|
||||
* @return the actual number of bytes written
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public int write(final byte[] src, final int timeoutMillis) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets various serial port parameters.
|
||||
*
|
||||
* @param baudRate baud rate as an integer, for example {@code 115200}.
|
||||
* @param dataBits one of {@link #DATABITS_5}, {@link #DATABITS_6},
|
||||
* {@link #DATABITS_7}, or {@link #DATABITS_8}.
|
||||
* @param stopBits one of {@link #STOPBITS_1}, {@link #STOPBITS_1_5}, or
|
||||
* {@link #STOPBITS_2}.
|
||||
* @param parity one of {@link #PARITY_NONE}, {@link #PARITY_ODD},
|
||||
* {@link #PARITY_EVEN}, {@link #PARITY_MARK}, or
|
||||
* {@link #PARITY_SPACE}.
|
||||
* @throws IOException on error setting the port parameters
|
||||
*/
|
||||
public void setParameters(
|
||||
int baudRate, int dataBits, int stopBits, int parity) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the CD (Carrier Detect) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getCD() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the CTS (Clear To Send) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getCTS() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the DSR (Data Set Ready) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getDSR() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the DTR (Data Terminal Ready) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getDTR() throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the DTR (Data Terminal Ready) bit on the underlying UART, if
|
||||
* supported.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public void setDTR(boolean value) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the RI (Ring Indicator) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getRI() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the RTS (Request To Send) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getRTS() throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the RTS (Request To Send) bit on the underlying UART, if
|
||||
* supported.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public void setRTS(boolean value) throws IOException;
|
||||
|
||||
/**
|
||||
* Flush non-transmitted output data and / or non-read input data
|
||||
* @param flushRX {@code true} to flush non-transmitted output data
|
||||
* @param flushTX {@code true} to flush non-read input data
|
||||
* @return {@code true} if the operation was successful, or
|
||||
* {@code false} if the operation is not supported by the driver or device
|
||||
* @throws IOException if an error occurred during flush
|
||||
*/
|
||||
public boolean purgeHwBuffers(boolean flushRX, boolean flushTX) throws IOException;
|
||||
|
||||
public List<UsbSerialPort> getPorts();
|
||||
}
|
||||
|
@ -0,0 +1,218 @@
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbManager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface for a single serial port.
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
*/
|
||||
public interface UsbSerialPort {
|
||||
|
||||
/** 5 data bits. */
|
||||
public static final int DATABITS_5 = 5;
|
||||
|
||||
/** 6 data bits. */
|
||||
public static final int DATABITS_6 = 6;
|
||||
|
||||
/** 7 data bits. */
|
||||
public static final int DATABITS_7 = 7;
|
||||
|
||||
/** 8 data bits. */
|
||||
public static final int DATABITS_8 = 8;
|
||||
|
||||
/** No flow control. */
|
||||
public static final int FLOWCONTROL_NONE = 0;
|
||||
|
||||
/** RTS/CTS input flow control. */
|
||||
public static final int FLOWCONTROL_RTSCTS_IN = 1;
|
||||
|
||||
/** RTS/CTS output flow control. */
|
||||
public static final int FLOWCONTROL_RTSCTS_OUT = 2;
|
||||
|
||||
/** XON/XOFF input flow control. */
|
||||
public static final int FLOWCONTROL_XONXOFF_IN = 4;
|
||||
|
||||
/** XON/XOFF output flow control. */
|
||||
public static final int FLOWCONTROL_XONXOFF_OUT = 8;
|
||||
|
||||
/** No parity. */
|
||||
public static final int PARITY_NONE = 0;
|
||||
|
||||
/** Odd parity. */
|
||||
public static final int PARITY_ODD = 1;
|
||||
|
||||
/** Even parity. */
|
||||
public static final int PARITY_EVEN = 2;
|
||||
|
||||
/** Mark parity. */
|
||||
public static final int PARITY_MARK = 3;
|
||||
|
||||
/** Space parity. */
|
||||
public static final int PARITY_SPACE = 4;
|
||||
|
||||
/** 1 stop bit. */
|
||||
public static final int STOPBITS_1 = 1;
|
||||
|
||||
/** 1.5 stop bits. */
|
||||
public static final int STOPBITS_1_5 = 3;
|
||||
|
||||
/** 2 stop bits. */
|
||||
public static final int STOPBITS_2 = 2;
|
||||
|
||||
public UsbSerialDriver getDriver();
|
||||
|
||||
/**
|
||||
* Opens and initializes the port. Upon success, caller must ensure that
|
||||
* {@link #close()} is eventually called.
|
||||
*
|
||||
* @param connection an open device connection, acquired with
|
||||
* {@link UsbManager#openDevice(android.hardware.usb.UsbDevice)}
|
||||
* @throws IOException on error opening or initializing the port.
|
||||
*/
|
||||
public void open(UsbDeviceConnection connection) throws IOException;
|
||||
|
||||
/**
|
||||
* Closes the port.
|
||||
*
|
||||
* @throws IOException on error closing the port.
|
||||
*/
|
||||
public void close() throws IOException;
|
||||
|
||||
/**
|
||||
* Reads as many bytes as possible into the destination buffer.
|
||||
*
|
||||
* @param dest the destination byte buffer
|
||||
* @param timeoutMillis the timeout for reading
|
||||
* @return the actual number of bytes read
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public int read(final byte[] dest, final int timeoutMillis) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes as many bytes as possible from the source buffer.
|
||||
*
|
||||
* @param src the source byte buffer
|
||||
* @param timeoutMillis the timeout for writing
|
||||
* @return the actual number of bytes written
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public int write(final byte[] src, final int timeoutMillis) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets various serial port parameters.
|
||||
*
|
||||
* @param baudRate baud rate as an integer, for example {@code 115200}.
|
||||
* @param dataBits one of {@link #DATABITS_5}, {@link #DATABITS_6},
|
||||
* {@link #DATABITS_7}, or {@link #DATABITS_8}.
|
||||
* @param stopBits one of {@link #STOPBITS_1}, {@link #STOPBITS_1_5}, or
|
||||
* {@link #STOPBITS_2}.
|
||||
* @param parity one of {@link #PARITY_NONE}, {@link #PARITY_ODD},
|
||||
* {@link #PARITY_EVEN}, {@link #PARITY_MARK}, or
|
||||
* {@link #PARITY_SPACE}.
|
||||
* @throws IOException on error setting the port parameters
|
||||
*/
|
||||
public void setParameters(
|
||||
int baudRate, int dataBits, int stopBits, int parity) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the CD (Carrier Detect) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getCD() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the CTS (Clear To Send) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getCTS() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the DSR (Data Set Ready) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getDSR() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the DTR (Data Terminal Ready) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getDTR() throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the DTR (Data Terminal Ready) bit on the underlying UART, if
|
||||
* supported.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public void setDTR(boolean value) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the RI (Ring Indicator) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getRI() throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the RTS (Request To Send) bit from the underlying UART.
|
||||
*
|
||||
* @return the current state, or {@code false} if not supported.
|
||||
* @throws IOException if an error occurred during reading
|
||||
*/
|
||||
public boolean getRTS() throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the RTS (Request To Send) bit on the underlying UART, if
|
||||
* supported.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public void setRTS(boolean value) throws IOException;
|
||||
|
||||
/**
|
||||
* Flush non-transmitted output data and / or non-read input data
|
||||
* @param flushRX {@code true} to flush non-transmitted output data
|
||||
* @param flushTX {@code true} to flush non-read input data
|
||||
* @return {@code true} if the operation was successful, or
|
||||
* {@code false} if the operation is not supported by the driver or device
|
||||
* @throws IOException if an error occurred during flush
|
||||
*/
|
||||
public boolean purgeHwBuffers(boolean flushRX, boolean flushTX) throws IOException;
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
/* Copyright 2011 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,233 +16,79 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbManager;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helper class which finds compatible {@link UsbDevice}s and creates
|
||||
* {@link UsbSerialDriver} instances.
|
||||
*
|
||||
* <p/>
|
||||
* You don't need a Prober to use the rest of the library: it is perfectly
|
||||
* acceptable to instantiate driver instances manually. The Prober simply
|
||||
* provides convenience functions.
|
||||
*
|
||||
* <p/>
|
||||
* For most drivers, the corresponding {@link #probe(UsbManager, UsbDevice)}
|
||||
* method will either return an empty list (device unknown / unsupported) or a
|
||||
* singleton list. However, multi-port drivers may return multiple instances.
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
*/
|
||||
public enum UsbSerialProber {
|
||||
public class UsbSerialProber {
|
||||
|
||||
// TODO(mikey): Too much boilerplate.
|
||||
private final ProbeTable mProbeTable;
|
||||
|
||||
/**
|
||||
* Prober for {@link FtdiSerialDriver}.
|
||||
*
|
||||
* @see FtdiSerialDriver
|
||||
*/
|
||||
FTDI_SERIAL {
|
||||
@Override
|
||||
public List<UsbSerialDriver> probe(final UsbManager manager, final UsbDevice usbDevice) {
|
||||
if (!testIfSupported(usbDevice, FtdiSerialDriver.getSupportedDevices())) {
|
||||
return Collections.emptyList();
|
||||
public UsbSerialProber(ProbeTable probeTable) {
|
||||
mProbeTable = probeTable;
|
||||
}
|
||||
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
|
||||
if (connection == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final UsbSerialDriver driver = new FtdiSerialDriver(usbDevice, connection);
|
||||
return Collections.singletonList(driver);
|
||||
}
|
||||
},
|
||||
|
||||
CDC_ACM_SERIAL {
|
||||
@Override
|
||||
public List<UsbSerialDriver> probe(UsbManager manager, UsbDevice usbDevice) {
|
||||
if (!testIfSupported(usbDevice, CdcAcmSerialDriver.getSupportedDevices())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
|
||||
if (connection == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final UsbSerialDriver driver = new CdcAcmSerialDriver(usbDevice, connection);
|
||||
return Collections.singletonList(driver);
|
||||
}
|
||||
},
|
||||
|
||||
SILAB_SERIAL {
|
||||
@Override
|
||||
public List<UsbSerialDriver> probe(final UsbManager manager, final UsbDevice usbDevice) {
|
||||
if (!testIfSupported(usbDevice, Cp2102SerialDriver.getSupportedDevices())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
|
||||
if (connection == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final UsbSerialDriver driver = new Cp2102SerialDriver(usbDevice, connection);
|
||||
return Collections.singletonList(driver);
|
||||
}
|
||||
},
|
||||
|
||||
PROLIFIC_SERIAL {
|
||||
@Override
|
||||
public List<UsbSerialDriver> probe(final UsbManager manager, final UsbDevice usbDevice) {
|
||||
if (!testIfSupported(usbDevice, ProlificSerialDriver.getSupportedDevices())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
|
||||
if (connection == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final UsbSerialDriver driver = new ProlificSerialDriver(usbDevice, connection);
|
||||
return Collections.singletonList(driver);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests the supplied {@link UsbDevice} for compatibility with this enum
|
||||
* member, returning one or more driver instances if compatible.
|
||||
*
|
||||
* @param manager the {@link UsbManager} to use
|
||||
* @param usbDevice the raw {@link UsbDevice} to use
|
||||
* @return zero or more {@link UsbSerialDriver}, depending on compatibility
|
||||
* (never {@code null}).
|
||||
*/
|
||||
protected abstract List<UsbSerialDriver> probe(final UsbManager manager, final UsbDevice usbDevice);
|
||||
|
||||
/**
|
||||
* Creates and returns a new {@link UsbSerialDriver} instance for the first
|
||||
* compatible {@link UsbDevice} found on the bus. If none are found,
|
||||
* returns {@code null}.
|
||||
*
|
||||
* <p/>
|
||||
* The order of devices is undefined, therefore if there are multiple
|
||||
* devices on the bus, the chosen device may not be predictable (clients
|
||||
* should use {@link #findAllDevices(UsbManager)} instead).
|
||||
*
|
||||
* @param usbManager the {@link UsbManager} to use.
|
||||
* @return the first available {@link UsbSerialDriver}, or {@code null} if
|
||||
* none are available.
|
||||
*/
|
||||
public static UsbSerialDriver findFirstDevice(final UsbManager usbManager) {
|
||||
for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
|
||||
for (final UsbSerialProber prober : values()) {
|
||||
final List<UsbSerialDriver> probedDevices = prober.probe(usbManager, usbDevice);
|
||||
if (!probedDevices.isEmpty()) {
|
||||
return probedDevices.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public static UsbSerialProber getDefaultProber() {
|
||||
final ProbeTable probeTable = new ProbeTable();
|
||||
probeTable.addDriver(CdcAcmSerialDriver.class);
|
||||
probeTable.addDriver(Cp2102SerialDriver.class);
|
||||
probeTable.addDriver(FtdiSerialDriver.class);
|
||||
probeTable.addDriver(ProlificSerialDriver.class);
|
||||
return new UsbSerialProber(probeTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link UsbSerialDriver} instance for all compatible
|
||||
* {@link UsbDevice}s found on the bus. If no compatible devices are found,
|
||||
* the list will be empty.
|
||||
* Finds and builds all possible {@link UsbSerialDriver UsbSerialDrivers}
|
||||
* from the currently-attached {@link UsbDevice} hierarchy. This method does
|
||||
* not require permission from the Android USB system, since it does not
|
||||
* open any of the devices.
|
||||
*
|
||||
* @param usbManager
|
||||
* @return
|
||||
* @return a list, possibly empty, of all compatible drivers
|
||||
*/
|
||||
public static List<UsbSerialDriver> findAllDevices(final UsbManager usbManager) {
|
||||
public List<UsbSerialDriver> findAllDrivers(final UsbManager usbManager) {
|
||||
final List<UsbSerialDriver> result = new ArrayList<UsbSerialDriver>();
|
||||
|
||||
// For each UsbDevice, call probe() for each prober.
|
||||
for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
|
||||
result.addAll(probeSingleDevice(usbManager, usbDevice));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special method for testing a specific device for driver support,
|
||||
* returning any compatible driver(s).
|
||||
*
|
||||
* <p/>
|
||||
* Clients should ordinarily use {@link #findAllDevices(UsbManager)}, which
|
||||
* operates against the entire bus of devices. This method is useful when
|
||||
* testing against only a single target is desired.
|
||||
*
|
||||
* @param usbManager the {@link UsbManager} to use.
|
||||
* @param usbDevice the device to test against.
|
||||
* @return a list containing zero or more {@link UsbSerialDriver} instances.
|
||||
*/
|
||||
public static List<UsbSerialDriver> probeSingleDevice(final UsbManager usbManager,
|
||||
UsbDevice usbDevice) {
|
||||
final List<UsbSerialDriver> result = new ArrayList<UsbSerialDriver>();
|
||||
for (final UsbSerialProber prober : values()) {
|
||||
final List<UsbSerialDriver> probedDevices = prober.probe(usbManager, usbDevice);
|
||||
result.addAll(probedDevices);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated; Use {@link #findFirstDevice(UsbManager)}.
|
||||
*
|
||||
* @param usbManager
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static UsbSerialDriver acquire(final UsbManager usbManager) {
|
||||
return findFirstDevice(usbManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated; use {@link #probeSingleDevice(UsbManager, UsbDevice)}.
|
||||
*
|
||||
* @param usbManager
|
||||
* @param usbDevice
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static UsbSerialDriver acquire(final UsbManager usbManager, final UsbDevice usbDevice) {
|
||||
final List<UsbSerialDriver> probedDevices = probeSingleDevice(usbManager, usbDevice);
|
||||
if (!probedDevices.isEmpty()) {
|
||||
return probedDevices.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given device is found in the driver's
|
||||
* vendor/product map.
|
||||
*
|
||||
* @param usbDevice the device to test
|
||||
* @param supportedDevices map of vendor IDs to product ID(s)
|
||||
* @return {@code true} if supported
|
||||
*/
|
||||
private static boolean testIfSupported(final UsbDevice usbDevice,
|
||||
final Map<Integer, int[]> supportedDevices) {
|
||||
final int[] supportedProducts = supportedDevices.get(
|
||||
Integer.valueOf(usbDevice.getVendorId()));
|
||||
if (supportedProducts == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int vendorId = usbDevice.getVendorId();
|
||||
final int productId = usbDevice.getProductId();
|
||||
for (int supportedProductId : supportedProducts) {
|
||||
if (productId == supportedProductId) {
|
||||
return true;
|
||||
|
||||
final Class<? extends UsbSerialDriver> driverClass =
|
||||
mProbeTable.findDriver(vendorId, productId);
|
||||
if (driverClass != null) {
|
||||
final UsbSerialDriver driver;
|
||||
try {
|
||||
final Constructor<? extends UsbSerialDriver> ctor =
|
||||
driverClass.getConstructor(UsbDevice.class);
|
||||
driver = ctor.newInstance(usbDevice);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
result.add(driver);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright 2011 Google Inc.
|
||||
/* Copyright 2011-2013 Google Inc.
|
||||
* Copyright 2013 mike wakerly <opensource@hoho.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,7 +16,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
||||
* Project home page: https://github.com/mik3y/usb-serial-for-android
|
||||
*/
|
||||
|
||||
package com.hoho.android.usbserial.util;
|
||||
@ -23,13 +24,13 @@ package com.hoho.android.usbserial.util;
|
||||
import android.hardware.usb.UsbRequest;
|
||||
import android.util.Log;
|
||||
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Utility class which services a {@link UsbSerialDriver} in its {@link #run()}
|
||||
* Utility class which services a {@link UsbSerialPort} in its {@link #run()}
|
||||
* method.
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
@ -42,7 +43,7 @@ public class SerialInputOutputManager implements Runnable {
|
||||
private static final int READ_WAIT_MILLIS = 200;
|
||||
private static final int BUFSIZ = 4096;
|
||||
|
||||
private final UsbSerialDriver mDriver;
|
||||
private final UsbSerialPort mDriver;
|
||||
|
||||
private final ByteBuffer mReadBuffer = ByteBuffer.allocate(BUFSIZ);
|
||||
|
||||
@ -77,14 +78,14 @@ public class SerialInputOutputManager implements Runnable {
|
||||
/**
|
||||
* Creates a new instance with no listener.
|
||||
*/
|
||||
public SerialInputOutputManager(UsbSerialDriver driver) {
|
||||
public SerialInputOutputManager(UsbSerialPort driver) {
|
||||
this(driver, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the provided listener.
|
||||
*/
|
||||
public SerialInputOutputManager(UsbSerialDriver driver, Listener listener) {
|
||||
public SerialInputOutputManager(UsbSerialPort driver, Listener listener) {
|
||||
mDriver = driver;
|
||||
mListener = listener;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user