Commit 6243dbac authored by Don Gagne's avatar Don Gagne

parent 6580a544
...@@ -41,8 +41,8 @@ public class CdcAcmSerialDriver extends CommonUsbSerialDriver { ...@@ -41,8 +41,8 @@ public class CdcAcmSerialDriver extends CommonUsbSerialDriver {
private static final int SET_CONTROL_LINE_STATE = 0x22; private static final int SET_CONTROL_LINE_STATE = 0x22;
private static final int SEND_BREAK = 0x23; private static final int SEND_BREAK = 0x23;
public CdcAcmSerialDriver(UsbDevice device, UsbDeviceConnection connection) { public CdcAcmSerialDriver(UsbDevice device) {
super(device, connection); super(device);
} }
@Override @Override
......
...@@ -35,11 +35,13 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver { ...@@ -35,11 +35,13 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver {
public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024; public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024; public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
protected final UsbDevice mDevice; protected final UsbDevice mDevice;
protected final UsbDeviceConnection mConnection; protected final Object mReadBufferLock = new Object();
protected final Object mWriteBufferLock = new Object();
protected final Object mReadBufferLock = new Object(); protected UsbDeviceConnection mConnection = null;
protected final Object mWriteBufferLock = new Object();
private int _permissionStatus = permissionStatusRequestRequired;
/** Internal read buffer. Guarded by {@link #mReadBufferLock}. */ /** Internal read buffer. Guarded by {@link #mReadBufferLock}. */
protected byte[] mReadBuffer; protected byte[] mReadBuffer;
...@@ -47,14 +49,28 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver { ...@@ -47,14 +49,28 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver {
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */ /** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
protected byte[] mWriteBuffer; protected byte[] mWriteBuffer;
public CommonUsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) { public CommonUsbSerialDriver(UsbDevice device) {
mDevice = device; mDevice = device;
mConnection = connection;
mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE]; mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE];
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE]; mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
} }
@Override
public void setConnection(UsbDeviceConnection connection) {
mConnection = connection;
}
@Override
public int permissionStatus() {
return _permissionStatus;
}
@Override
public void setPermissionStatus(int permissionStatus) {
_permissionStatus = permissionStatus;
}
/** /**
* Returns the currently-bound USB device. * Returns the currently-bound USB device.
* *
......
...@@ -61,8 +61,8 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver { ...@@ -61,8 +61,8 @@ public class Cp2102SerialDriver extends CommonUsbSerialDriver {
private UsbEndpoint mReadEndpoint; private UsbEndpoint mReadEndpoint;
private UsbEndpoint mWriteEndpoint; private UsbEndpoint mWriteEndpoint;
public Cp2102SerialDriver(UsbDevice device, UsbDeviceConnection connection) { public Cp2102SerialDriver(UsbDevice device) {
super(device, connection); super(device);
} }
private int setConfigSingle(int request, int value) { private int setConfigSingle(int request, int value) {
......
...@@ -211,8 +211,8 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver { ...@@ -211,8 +211,8 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
* @throws UsbSerialRuntimeException if the given device is incompatible * @throws UsbSerialRuntimeException if the given device is incompatible
* with this driver * with this driver
*/ */
public FtdiSerialDriver(UsbDevice usbDevice, UsbDeviceConnection usbConnection) { public FtdiSerialDriver(UsbDevice usbDevice) {
super(usbDevice, usbConnection); super(usbDevice);
mType = null; mType = null;
} }
......
...@@ -231,8 +231,8 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver { ...@@ -231,8 +231,8 @@ public class ProlificSerialDriver extends CommonUsbSerialDriver {
return ((getStatus() & flag) == flag); return ((getStatus() & flag) == flag);
} }
public ProlificSerialDriver(UsbDevice device, UsbDeviceConnection connection) { public ProlificSerialDriver(UsbDevice device) {
super(device, connection); super(device);
} }
@Override @Override
......
...@@ -83,6 +83,16 @@ public interface UsbSerialDriver { ...@@ -83,6 +83,16 @@ public interface UsbSerialDriver {
/** 2 stop bits. */ /** 2 stop bits. */
public static final int STOPBITS_2 = 2; public static final int STOPBITS_2 = 2;
public static final int permissionStatusSuccess = 0;
public static final int permissionStatusDenied = 1;
public static final int permissionStatusRequested = 2;
public static final int permissionStatusRequestRequired = 3;
public static final int permissionStatusOpen = 4;
public int permissionStatus();
public void setPermissionStatus(int permissionStatus);
public void setConnection(UsbDeviceConnection connection);
/** /**
* Returns the currently-bound USB device. * Returns the currently-bound USB device.
* *
......
...@@ -65,11 +65,7 @@ public enum UsbSerialProber { ...@@ -65,11 +65,7 @@ public enum UsbSerialProber {
if (!testIfSupported(usbDevice, FtdiSerialDriver.getSupportedDevices())) { if (!testIfSupported(usbDevice, FtdiSerialDriver.getSupportedDevices())) {
return Collections.emptyList(); return Collections.emptyList();
} }
final UsbDeviceConnection connection = manager.openDevice(usbDevice); final UsbSerialDriver driver = new FtdiSerialDriver(usbDevice);
if (connection == null) {
return Collections.emptyList();
}
final UsbSerialDriver driver = new FtdiSerialDriver(usbDevice, connection);
return Collections.singletonList(driver); return Collections.singletonList(driver);
} }
}, },
...@@ -80,11 +76,7 @@ public enum UsbSerialProber { ...@@ -80,11 +76,7 @@ public enum UsbSerialProber {
if (!testIfSupported(usbDevice, CdcAcmSerialDriver.getSupportedDevices())) { if (!testIfSupported(usbDevice, CdcAcmSerialDriver.getSupportedDevices())) {
return Collections.emptyList(); return Collections.emptyList();
} }
final UsbDeviceConnection connection = manager.openDevice(usbDevice); final UsbSerialDriver driver = new CdcAcmSerialDriver(usbDevice);
if (connection == null) {
return Collections.emptyList();
}
final UsbSerialDriver driver = new CdcAcmSerialDriver(usbDevice, connection);
return Collections.singletonList(driver); return Collections.singletonList(driver);
} }
}, },
...@@ -95,11 +87,7 @@ public enum UsbSerialProber { ...@@ -95,11 +87,7 @@ public enum UsbSerialProber {
if (!testIfSupported(usbDevice, Cp2102SerialDriver.getSupportedDevices())) { if (!testIfSupported(usbDevice, Cp2102SerialDriver.getSupportedDevices())) {
return Collections.emptyList(); return Collections.emptyList();
} }
final UsbDeviceConnection connection = manager.openDevice(usbDevice); final UsbSerialDriver driver = new Cp2102SerialDriver(usbDevice);
if (connection == null) {
return Collections.emptyList();
}
final UsbSerialDriver driver = new Cp2102SerialDriver(usbDevice, connection);
return Collections.singletonList(driver); return Collections.singletonList(driver);
} }
}, },
...@@ -110,11 +98,7 @@ public enum UsbSerialProber { ...@@ -110,11 +98,7 @@ public enum UsbSerialProber {
if (!testIfSupported(usbDevice, ProlificSerialDriver.getSupportedDevices())) { if (!testIfSupported(usbDevice, ProlificSerialDriver.getSupportedDevices())) {
return Collections.emptyList(); return Collections.emptyList();
} }
final UsbDeviceConnection connection = manager.openDevice(usbDevice); final UsbSerialDriver driver = new ProlificSerialDriver(usbDevice);
if (connection == null) {
return Collections.emptyList();
}
final UsbSerialDriver driver = new ProlificSerialDriver(usbDevice, connection);
return Collections.singletonList(driver); return Collections.singletonList(driver);
} }
}; };
......
...@@ -31,11 +31,13 @@ package org.mavlink.qgroundcontrol; ...@@ -31,11 +31,13 @@ package org.mavlink.qgroundcontrol;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.io.IOException; import java.io.IOException;
import android.app.Activity; import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
...@@ -53,81 +55,136 @@ import org.qtproject.qt5.android.bindings.QtApplication; ...@@ -53,81 +55,136 @@ import org.qtproject.qt5.android.bindings.QtApplication;
public class QGCActivity extends QtActivity public class QGCActivity extends QtActivity
{ {
public static int BAD_PORT = 0; public static int BAD_DEVICE_ID = 0;
private static QGCActivity m_instance; private static QGCActivity _instance = null;
private static UsbManager m_manager; // ANDROID USB HOST CLASS private static UsbManager _usbManager = null;
private static List<UsbSerialDriver> m_devices; // LIST OF CURRENT DEVICES private static List<UsbSerialDriver> _drivers;
private static HashMap<Integer, UsbSerialDriver> m_openedDevices; // LIST OF OPENED DEVICES private static HashMap<Integer, UsbIoManager> m_ioManager;
private static HashMap<Integer, UsbIoManager> m_ioManager; // THREADS FOR LISTENING FOR INCOMING DATA private static HashMap<Integer, Integer> _userDataHashByDeviceId;
private static HashMap<Integer, Integer> m_userData; // CORRESPONDING USER DATA FOR OPENED DEVICES. USED IN DISCONNECT CALLBACK private static final String TAG = "QGC_QGCActivity";
// USED TO DETECT WHEN A DEVICE HAS BEEN UNPLUGGED private static PowerManager.WakeLock _wakeLock;
private BroadcastReceiver m_UsbReceiver = null; private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private final static ExecutorService m_Executor = Executors.newSingleThreadExecutor(); private static PendingIntent _usbPermissionIntent = null;
private static final String TAG = "QGC_QGCActivity";
private static PowerManager.WakeLock m_wl;
public static Context m_context; public static Context m_context;
private final static ExecutorService m_Executor = Executors.newSingleThreadExecutor();
private final static UsbIoManager.Listener m_Listener = private final static UsbIoManager.Listener m_Listener =
new UsbIoManager.Listener() new UsbIoManager.Listener()
{ {
@Override @Override
public void onRunError(Exception eA, int userDataA) public void onRunError(Exception eA, int userData)
{ {
Log.e(TAG, "onRunError Exception"); Log.e(TAG, "onRunError Exception");
nativeDeviceException(userDataA, eA.getMessage()); nativeDeviceException(userData, eA.getMessage());
} }
@Override @Override
public void onNewData(final byte[] dataA, int userDataA) public void onNewData(final byte[] dataA, int userData)
{ {
nativeDeviceNewData(userDataA, dataA); nativeDeviceNewData(userData, dataA);
} }
}; };
// NATIVE C++ FUNCTION THAT WILL BE CALLED IF THE DEVICE IS UNPLUGGED private static UsbSerialDriver _findDriverByDeviceId(int deviceId) {
private static native void nativeDeviceHasDisconnected(int userDataA); for (UsbSerialDriver driver: _drivers) {
private static native void nativeDeviceException(int userDataA, String messageA); if (driver.getDevice().getDeviceId() == deviceId) {
private static native void nativeDeviceNewData(int userDataA, byte[] dataA); return driver;
}
}
return null;
}
private static UsbSerialDriver _findDriverByDeviceName(String deviceName) {
for (UsbSerialDriver driver: _drivers) {
if (driver.getDevice().getDeviceName().equals(deviceName)) {
return driver;
}
}
return null;
}
private final static BroadcastReceiver _usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i(TAG, "BroadcastReceiver USB action " + action);
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (_instance) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
UsbSerialDriver driver = _findDriverByDeviceId(device.getDeviceId());
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
qgcLogDebug("Permission granted to " + device.getDeviceName());
driver.setPermissionStatus(UsbSerialDriver.permissionStatusSuccess);
} else {
qgcLogDebug("Permission denied for " + device.getDeviceName());
driver.setPermissionStatus(UsbSerialDriver.permissionStatusDenied);
}
}
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
if (_userDataHashByDeviceId.containsKey(device.getDeviceId())) {
nativeDeviceHasDisconnected(_userDataHashByDeviceId.get(device.getDeviceId()));
}
}
}
}
};
// Native C++ functions which connect back to QSerialPort code
private static native void nativeDeviceHasDisconnected(int userData);
private static native void nativeDeviceException(int userData, String messageA);
private static native void nativeDeviceNewData(int userData, byte[] dataA);
// Native C++ functions called to log output // Native C++ functions called to log output
public static native void qgcLogDebug(String message); public static native void qgcLogDebug(String message);
public static native void qgcLogWarning(String message); public static native void qgcLogWarning(String message);
//////////////////////////////////////////////////////////////////////////////////////////////// // QGCActivity singleton
//
// Constructor. Only used once to create the initial instance for the static functions.
//
////////////////////////////////////////////////////////////////////////////////////////////////
public QGCActivity() public QGCActivity()
{ {
m_instance = this; _instance = this;
m_openedDevices = new HashMap<Integer, UsbSerialDriver>(); _drivers = new ArrayList<UsbSerialDriver>();
m_userData = new HashMap<Integer, Integer>(); _userDataHashByDeviceId = new HashMap<Integer, Integer>();
m_ioManager = new HashMap<Integer, UsbIoManager>(); m_ioManager = new HashMap<Integer, UsbIoManager>();
Log.i(TAG, "Instance created");
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
PowerManager pm = (PowerManager)m_instance.getSystemService(Context.POWER_SERVICE); PowerManager pm = (PowerManager)_instance.getSystemService(Context.POWER_SERVICE);
m_wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "QGroundControl"); _wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "QGroundControl");
if(m_wl != null) { if(_wakeLock != null) {
m_wl.acquire(); _wakeLock.acquire();
Log.i(TAG, "SCREEN_BRIGHT_WAKE_LOCK acquired.");
} else { } else {
Log.i(TAG, "SCREEN_BRIGHT_WAKE_LOCK not acquired!!!"); Log.i(TAG, "SCREEN_BRIGHT_WAKE_LOCK not acquired!!!");
} }
m_instance.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); _instance.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
_usbManager = (UsbManager)_instance.getSystemService(Context.USB_SERVICE);
// Register for USB Detach and USB Permission intent
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.addAction(ACTION_USB_PERMISSION);
_instance.registerReceiver(_instance._usbReceiver, filter);
// Create intent for usb permission request
_usbPermissionIntent = PendingIntent.getBroadcast(_instance, 0, new Intent(ACTION_USB_PERMISSION), 0);
} }
@Override @Override
protected void onDestroy() { protected void onDestroy()
{
try { try {
if(m_wl != null) { if(_wakeLock != null) {
m_wl.release(); _wakeLock.release();
Log.i(TAG, "SCREEN_BRIGHT_WAKE_LOCK released.");
} }
} catch(Exception e) { } catch(Exception e) {
Log.e(TAG, "Exception onDestroy()"); Log.e(TAG, "Exception onDestroy()");
...@@ -138,225 +195,156 @@ public class QGCActivity extends QtActivity ...@@ -138,225 +195,156 @@ public class QGCActivity extends QtActivity
public void onInit(int status) { public void onInit(int status) {
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////// /// Incrementally updates the list of drivers connected to the device
// private static void updateCurrentDrivers()
// Find all current devices that match the device filter described in the androidmanifest.xml and the
// device_filter.xml
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
private static boolean getCurrentDevices()
{ {
if (m_instance == null) List<UsbSerialDriver> currentDrivers = UsbSerialProber.findAllDevices(_usbManager);
return false;
// Remove stale drivers
if (m_manager == null) for (int i=_drivers.size()-1; i>=0; i--) {
m_manager = (UsbManager)m_instance.getSystemService(Context.USB_SERVICE); boolean found = false;
for (UsbSerialDriver currentDriver: currentDrivers) {
if (_drivers.get(i).getDevice().getDeviceId() == currentDriver.getDevice().getDeviceId()) {
found = true;
break;
}
}
if (m_devices != null) if (!found) {
m_devices.clear(); qgcLogDebug("Remove stale driver " + _drivers.get(i).getDevice().getDeviceName());
_drivers.remove(i);
}
}
m_devices = UsbSerialProber.findAllDevices(m_manager); // Add new drivers
for (int i=0; i<currentDrivers.size(); i++) {
boolean found = false;
for (int j=0; j<_drivers.size(); j++) {
if (currentDrivers.get(i).getDevice().getDeviceId() == _drivers.get(j).getDevice().getDeviceId()) {
found = true;
break;
}
}
return true; if (!found) {
UsbSerialDriver newDriver = currentDrivers.get(i);
UsbDevice device = newDriver.getDevice();
String deviceName = device.getDeviceName();
_drivers.add(newDriver);
qgcLogDebug("Adding new driver " + deviceName);
// Request permission if needed
if (_usbManager.hasPermission(device)) {
qgcLogDebug("Already have permission to use device " + deviceName);
newDriver.setPermissionStatus(UsbSerialDriver.permissionStatusSuccess);
} else {
qgcLogDebug("Requesting permission to use device " + deviceName);
newDriver.setPermissionStatus(UsbSerialDriver.permissionStatusRequested);
_usbManager.requestPermission(device, _usbPermissionIntent);
}
}
}
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////// /// Returns array of device info for each unopened device.
// /// @return Device info format DeviceName:Company:ProductId:VendorId
// List all available devices that are not already open. It returns the serial port info
// in a : separated string array. Each string entry consists of the following:
//
// DeviceName:Company:ProductId:VendorId
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
public static String[] availableDevicesInfo() public static String[] availableDevicesInfo()
{ {
// GET THE LIST OF CURRENT DEVICES updateCurrentDrivers();
if (!getCurrentDevices())
{
Log.e(TAG, "QGCActivity instance not present");
return null;
}
// MAKE SURE WE HAVE ENTRIES if (_drivers.size() <= 0) {
if (m_devices.size() <= 0)
{
//Log.e(TAG, "No USB devices found");
return null; return null;
} }
if (m_openedDevices == null) List<String> deviceInfoList = new ArrayList<String>();
{
Log.e(TAG, "m_openedDevices is null");
return null;
}
int countL = 0; for (int i=0; i<_drivers.size(); i++) {
int iL; String deviceInfo;
UsbSerialDriver driver = _drivers.get(i);
// CHECK FOR ALREADY OPENED DEVICES AND DON"T INCLUDE THEM IN THE COUNT if (driver.permissionStatus() != UsbSerialDriver.permissionStatusSuccess) {
for (iL=0; iL<m_devices.size(); iL++) continue;
{
if (m_openedDevices.get(m_devices.get(iL).getDevice().getDeviceId()) != null)
{
countL++;
break;
} }
}
if (m_devices.size() - countL <= 0) UsbDevice device = driver.getDevice();
{
//Log.e(TAG, "No open USB devices found");
return null;
}
String[] listL = new String[m_devices.size() - countL]; deviceInfo = device.getDeviceName() + ":";
UsbSerialDriver driverL;
String tempL;
// GET THE DATA ON THE INDIVIDUAL DEVICES SKIPPING THE ONES THAT ARE ALREADY OPEN if (driver instanceof FtdiSerialDriver) {
countL = 0; deviceInfo = deviceInfo + "FTDI:";
for (iL=0; iL<m_devices.size(); iL++) } else if (driver instanceof CdcAcmSerialDriver) {
{ deviceInfo = deviceInfo + "Cdc Acm:";
driverL = m_devices.get(iL); } else if (driver instanceof Cp2102SerialDriver) {
if (m_openedDevices.get(driverL.getDevice().getDeviceId()) == null) deviceInfo = deviceInfo + "Cp2102:";
{ } else if (driver instanceof ProlificSerialDriver) {
UsbDevice deviceL = driverL.getDevice(); deviceInfo = deviceInfo + "Prolific:";
tempL = deviceL.getDeviceName() + ":"; } else {
deviceInfo = deviceInfo + "Unknown:";
if (driverL instanceof FtdiSerialDriver)
tempL = tempL + "FTDI:";
else if (driverL instanceof CdcAcmSerialDriver)
tempL = tempL + "Cdc Acm:";
else if (driverL instanceof Cp2102SerialDriver)
tempL = tempL + "Cp2102:";
else if (driverL instanceof ProlificSerialDriver)
tempL = tempL + "Prolific:";
else
tempL = tempL + "Unknown:";
tempL = tempL + Integer.toString(deviceL.getProductId()) + ":";
tempL = tempL + Integer.toString(deviceL.getVendorId()) + ":";
listL[countL] = tempL;
countL++;
qgcLogDebug("Found " + tempL);
} }
}
return listL; deviceInfo = deviceInfo + Integer.toString(device.getProductId()) + ":";
} deviceInfo = deviceInfo + Integer.toString(device.getVendorId()) + ":";
deviceInfoList.add(deviceInfo);
}
String[] rgDeviceInfo = new String[deviceInfoList.size()];
for (int i=0; i<deviceInfoList.size(); i++) {
rgDeviceInfo[i] = deviceInfoList.get(i);
}
///////////////////////////////////////////////////////////////////////////////////////////////// return rgDeviceInfo;
// }
// Open a device based on the name.
// /// Open the specified device
// Args: nameA - name of the device to open /// @param userData Data to associate with device and pass back through to native calls.
// userDataA - C++ pointer to the QSerialPort that is trying to open the device. This is /// @return Device id
// used by the detector to inform the C++ side if it is unplugged public static int open(Context parentContext, String deviceName, int userData)
//
// Returns: ID number of opened port. This number is used to reference the correct port in subsequent
// calls like close(), read(), and write().
//
/////////////////////////////////////////////////////////////////////////////////////////////////
public static int open(Context parentContext, String nameA, int userDataA)
{ {
int idL = BAD_PORT; int deviceId = BAD_DEVICE_ID;
m_context = parentContext; m_context = parentContext;
//qgcLogDebug("Getting device list"); UsbSerialDriver driver = _findDriverByDeviceName(deviceName);
if (!getCurrentDevices()) if (driver == null) {
return BAD_PORT; qgcLogWarning("Attempt to open unknown device " + deviceName);
return BAD_DEVICE_ID;
// CHECK THAT PORT IS NOT ALREADY OPENED
if (m_openedDevices != null)
{
for (UsbSerialDriver driverL: m_openedDevices.values())
{
if (nameA.equals(driverL.getDevice().getDeviceName()))
{
Log.e(TAG, "Device already opened");
return BAD_PORT;
}
}
} }
else
return BAD_PORT;
if (m_devices == null) if (driver.permissionStatus() != UsbSerialDriver.permissionStatusSuccess) {
return BAD_PORT; qgcLogWarning("Attempt to open device with incorrect permission status " + deviceName + " " + driver.permissionStatus());
return BAD_DEVICE_ID;
}
// OPEN THE DEVICE UsbDevice device = driver.getDevice();
try deviceId = device.getDeviceId();
{
for (int iL=0; iL<m_devices.size(); iL++)
{
Log.i(TAG, "Checking device " + m_devices.get(iL).getDevice().getDeviceName() + " id: " + m_devices.get(iL).getDevice().getDeviceId());
if (nameA.equals(m_devices.get(iL).getDevice().getDeviceName()))
{
idL = m_devices.get(iL).getDevice().getDeviceId();
m_openedDevices.put(idL, m_devices.get(iL));
m_userData.put(idL, userDataA);
if (m_instance.m_UsbReceiver == null)
{
Log.i(TAG, "Creating new broadcast receiver");
m_instance.m_UsbReceiver= new BroadcastReceiver()
{
public void onReceive(Context contextA, Intent intentA)
{
String actionL = intentA.getAction();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(actionL))
{
UsbDevice deviceL = (UsbDevice)intentA.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (deviceL != null)
{
if (m_userData.containsKey(deviceL.getDeviceId()))
{
nativeDeviceHasDisconnected(m_userData.get(deviceL.getDeviceId()));
}
}
}
}
};
// TURN ON THE INTENT FILTER SO IT WILL DETECT AN UNPLUG SIGNAL
IntentFilter filterL = new IntentFilter();
filterL.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
m_instance.registerReceiver(m_instance.m_UsbReceiver, filterL);
}
m_openedDevices.get(idL).open(); try {
driver.setConnection(_usbManager.openDevice(device));
driver.open();
driver.setPermissionStatus(UsbSerialDriver.permissionStatusOpen);
// START UP THE IO MANAGER TO READ/WRITE DATA TO THE DEVICE _userDataHashByDeviceId.put(deviceId, userData);
UsbIoManager managerL = new UsbIoManager(m_openedDevices.get(idL), m_Listener, userDataA);
if (managerL == null)
Log.e(TAG, "UsbIoManager instance is null");
m_ioManager.put(idL, managerL);
m_Executor.submit(managerL);
Log.i(TAG, "Port open successful");
return idL;
}
}
return BAD_PORT; UsbIoManager ioManager = new UsbIoManager(driver, m_Listener, userData);
} m_ioManager.put(deviceId, ioManager);
catch(IOException exA) m_Executor.submit(ioManager);
{
if (idL != BAD_PORT)
{
m_openedDevices.remove(idL);
m_userData.remove(idL);
if(m_ioManager.get(idL) != null) qgcLogDebug("Port open successful");
m_ioManager.get(idL).stop(); } catch(IOException exA) {
driver.setPermissionStatus(UsbSerialDriver.permissionStatusRequestRequired);
_userDataHashByDeviceId.remove(deviceId);
m_ioManager.remove(idL); if(m_ioManager.get(deviceId) != null) {
m_ioManager.get(deviceId).stop();
m_ioManager.remove(deviceId);
} }
qgcLogWarning("Port open exception: " + exA.getMessage()); qgcLogWarning("Port open exception: " + exA.getMessage());
return BAD_PORT; return BAD_DEVICE_ID;
} }
return deviceId;
} }
public static void startIoManager(int idA) public static void startIoManager(int idA)
...@@ -364,12 +352,12 @@ public class QGCActivity extends QtActivity ...@@ -364,12 +352,12 @@ public class QGCActivity extends QtActivity
if (m_ioManager.get(idA) != null) if (m_ioManager.get(idA) != null)
return; return;
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return; return;
UsbIoManager managerL = new UsbIoManager(driverL, m_Listener, m_userData.get(idA)); UsbIoManager managerL = new UsbIoManager(driverL, m_Listener, _userDataHashByDeviceId.get(idA));
m_ioManager.put(idA, managerL); m_ioManager.put(idA, managerL);
m_Executor.submit(managerL); m_Executor.submit(managerL);
} }
...@@ -398,7 +386,7 @@ public class QGCActivity extends QtActivity ...@@ -398,7 +386,7 @@ public class QGCActivity extends QtActivity
//////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public static boolean setParameters(int idA, int baudRateA, int dataBitsA, int stopBitsA, int parityA) public static boolean setParameters(int idA, int baudRateA, int dataBitsA, int stopBitsA, int parityA)
{ {
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return false; return false;
...@@ -427,7 +415,7 @@ public class QGCActivity extends QtActivity ...@@ -427,7 +415,7 @@ public class QGCActivity extends QtActivity
//////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public static boolean close(int idA) public static boolean close(int idA)
{ {
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return false; return false;
...@@ -435,8 +423,8 @@ public class QGCActivity extends QtActivity ...@@ -435,8 +423,8 @@ public class QGCActivity extends QtActivity
try try
{ {
stopIoManager(idA); stopIoManager(idA);
m_userData.remove(idA); _userDataHashByDeviceId.remove(idA);
m_openedDevices.remove(idA); driverL.setPermissionStatus(UsbSerialDriver.permissionStatusRequestRequired);
driverL.close(); driverL.close();
return true; return true;
...@@ -462,7 +450,7 @@ public class QGCActivity extends QtActivity ...@@ -462,7 +450,7 @@ public class QGCActivity extends QtActivity
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
public static int write(int idA, byte[] sourceA, int timeoutMSecA) public static int write(int idA, byte[] sourceA, int timeoutMSecA)
{ {
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return 0; return 0;
...@@ -488,51 +476,22 @@ public class QGCActivity extends QtActivity ...@@ -488,51 +476,22 @@ public class QGCActivity extends QtActivity
*/ */
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Determine if a device name if valid. Note, it does not look for devices that are already open
//
// Args: nameA - name of device to look for
//
// Returns: T/F
//
////////////////////////////////////////////////////////////////////////////////////////////////////
public static boolean isDeviceNameValid(String nameA) public static boolean isDeviceNameValid(String nameA)
{ {
if (m_devices.size() <= 0) for (UsbSerialDriver driver: _drivers) {
return false; if (driver.getDevice().getDeviceName() == nameA)
for (int iL=0; iL<m_devices.size(); iL++)
{
if (m_devices.get(iL).getDevice().getDeviceName() == nameA)
return true; return true;
} }
return false; return false;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Check if the device is open
//
// Args: nameA - name of device
//
// Returns: T/F
//
//////////////////////////////////////////////////////////////////////////////////////////////////////
public static boolean isDeviceNameOpen(String nameA) public static boolean isDeviceNameOpen(String nameA)
{ {
if (m_openedDevices == null) for (UsbSerialDriver driverL: _drivers) {
return false; if (nameA.equals(driverL.getDevice().getDeviceName()) && driverL.permissionStatus() == UsbSerialDriver.permissionStatusOpen) {
for (UsbSerialDriver driverL: m_openedDevices.values())
{
if (nameA.equals(driverL.getDevice().getDeviceName()))
return true; return true;
}
} }
return false; return false;
...@@ -554,7 +513,7 @@ public class QGCActivity extends QtActivity ...@@ -554,7 +513,7 @@ public class QGCActivity extends QtActivity
{ {
try try
{ {
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return false; return false;
...@@ -584,7 +543,7 @@ public class QGCActivity extends QtActivity ...@@ -584,7 +543,7 @@ public class QGCActivity extends QtActivity
{ {
try try
{ {
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return false; return false;
...@@ -615,7 +574,7 @@ public class QGCActivity extends QtActivity ...@@ -615,7 +574,7 @@ public class QGCActivity extends QtActivity
{ {
try try
{ {
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return false; return false;
...@@ -641,7 +600,7 @@ public class QGCActivity extends QtActivity ...@@ -641,7 +600,7 @@ public class QGCActivity extends QtActivity
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public static int getDeviceHandle(int idA) public static int getDeviceHandle(int idA)
{ {
UsbSerialDriver driverL = m_openedDevices.get(idA); UsbSerialDriver driverL = _findDriverByDeviceId(idA);
if (driverL == null) if (driverL == null)
return -1; return -1;
...@@ -652,21 +611,5 @@ public class QGCActivity extends QtActivity ...@@ -652,21 +611,5 @@ public class QGCActivity extends QtActivity
else else
return connectL.getFileDescriptor(); return connectL.getFileDescriptor();
} }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Get the open usb serial driver for the given id
//
// Args: idA - ID number from the open command
//
// Returns: usb device driver
//
/////////////////////////////////////////////////////////////////////////////////////////////
public static UsbSerialDriver getUsbSerialDriver(int idA)
{
return m_openedDevices.get(idA);
}
} }
...@@ -197,7 +197,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) ...@@ -197,7 +197,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
if (deviceId == BAD_PORT) if (deviceId == BAD_PORT)
{ {
qWarning() << "Error opening %s" << systemLocation.toLatin1().data(); qWarning() << "Error opening" << systemLocation.toLatin1().data();
q_ptr->setError(QSerialPort::DeviceNotFoundError); q_ptr->setError(QSerialPort::DeviceNotFoundError);
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment