Commit 9593ff3d authored by Don Gagne's avatar Don Gagne

Use FTDI driver provided by ftdicjip.com

- Fixes lost connections with FTDI radios
- Modified code to only test vendor id, all product ids are let through
- Modified code to pass log output through to C++ side
QGCLoggingCategory system
parent 81564629
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Everything --> <!-- Allow anything connected -->
<usb-device /> <usb-device />
<!-- 0x26AC / 0x11: PX4 FMU Pixhawk -->
<!--
<usb-device vendor-id="9900" product-id="17" />
-->
<!-- 0x0403 / 0x6001: FTDI FT232R UART -->
<!--
<usb-device vendor-id="1027" product-id="24577" />
-->
<!-- 0x0403 / 0x6015: FTDI FT231X -->
<!--
<usb-device vendor-id="1027" product-id="24597" />
-->
<!-- 0x2341 / Arduino -->
<!--
<usb-device vendor-id="9025" />
-->
<!-- 0x16C0 / 0x0483: Teensyduino -->
<!--
<usb-device vendor-id="5824" product-id="1155" />
-->
<!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
<!--
<usb-device vendor-id="4292" product-id="60000" />
-->
<!-- 0x067B / 0x2303: Prolific PL2303 -->
<!--
<usb-device vendor-id="1659" product-id="8963" />
-->
</resources> </resources>
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
* Project home page: http://code.google.com/p/usb-serial-for-android/ * Project home page: http://code.google.com/p/usb-serial-for-android/
*/ */
// IMPORTANT NOTE:
// This source has been modified from the original such that testIfSupported only tests for a vendor id
// match. If that matches it allows all product ids through. This provides for better match on unknown boards.
package com.hoho.android.usbserial.driver; package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDevice;
...@@ -230,21 +234,7 @@ public enum UsbSerialProber { ...@@ -230,21 +234,7 @@ public enum UsbSerialProber {
* @param supportedDevices map of vendor IDs to product ID(s) * @param supportedDevices map of vendor IDs to product ID(s)
* @return {@code true} if supported * @return {@code true} if supported
*/ */
private static boolean testIfSupported(final UsbDevice usbDevice, private static boolean testIfSupported(final UsbDevice usbDevice, final Map<Integer, int[]> supportedDevices) {
final Map<Integer, int[]> supportedDevices) { return supportedDevices.containsKey(usbDevice.getVendorId());
final int[] supportedProducts = supportedDevices.get(
Integer.valueOf(usbDevice.getVendorId()));
if (supportedProducts == null) {
return false;
}
final int productId = usbDevice.getProductId();
for (int supportedProductId : supportedProducts) {
if (productId == supportedProductId) {
return true;
}
}
return false;
} }
} }
...@@ -68,6 +68,8 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe ...@@ -68,6 +68,8 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
private static TextToSpeech m_tts; private static TextToSpeech m_tts;
private static PowerManager.WakeLock m_wl; private static PowerManager.WakeLock m_wl;
public static Context m_context;
private final static UsbIoManager.Listener m_Listener = private final static UsbIoManager.Listener m_Listener =
new UsbIoManager.Listener() new UsbIoManager.Listener()
{ {
...@@ -90,6 +92,10 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe ...@@ -90,6 +92,10 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
private static native void nativeDeviceException(int userDataA, String messageA); private static native void nativeDeviceException(int userDataA, String messageA);
private static native void nativeDeviceNewData(int userDataA, byte[] dataA); private static native void nativeDeviceNewData(int userDataA, byte[] dataA);
// Native C++ functions called to log output
public static native void qgcLogDebug(String message);
public static native void qgcLogWarning(String message);
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Constructor. Only used once to create the initial instance for the static functions. // Constructor. Only used once to create the initial instance for the static functions.
...@@ -252,7 +258,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe ...@@ -252,7 +258,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
tempL = tempL + Integer.toString(deviceL.getVendorId()) + ":"; tempL = tempL + Integer.toString(deviceL.getVendorId()) + ":";
listL[countL] = tempL; listL[countL] = tempL;
countL++; countL++;
//Log.i(TAG, "Found " + tempL); qgcLogDebug("Found " + tempL);
} }
} }
...@@ -273,11 +279,13 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe ...@@ -273,11 +279,13 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
// calls like close(), read(), and write(). // calls like close(), read(), and write().
// //
///////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////
public static int open(String nameA, int userDataA) public static int open(Context parentContext, String nameA, int userDataA)
{ {
int idL = BAD_PORT; int idL = BAD_PORT;
Log.i(TAG, "Getting device list"); m_context = parentContext;
//qgcLogDebug("Getting device list");
if (!getCurrentDevices()) if (!getCurrentDevices())
return BAD_PORT; return BAD_PORT;
...@@ -366,7 +374,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe ...@@ -366,7 +374,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
m_ioManager.remove(idL); m_ioManager.remove(idL);
} }
Log.e(TAG, "Port open exception"); qgcLogWarning("Port open exception: " + exA.getMessage());
return BAD_PORT; return BAD_PORT;
} }
} }
......
...@@ -46,10 +46,10 @@ ...@@ -46,10 +46,10 @@
#include <QtAndroidExtras/QtAndroidExtras> #include <QtAndroidExtras/QtAndroidExtras>
#include <QtAndroidExtras/QAndroidJniObject> #include <QtAndroidExtras/QAndroidJniObject>
#include <android/log.h>
#include "qserialport_android_p.h" #include "qserialport_android_p.h"
QGC_LOGGING_CATEGORY(AndroidSerialPortLog, "AndroidSerialPortLog")
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#define BAD_PORT 0 #define BAD_PORT 0
...@@ -91,6 +91,30 @@ static void jniDeviceException(JNIEnv *envA, jobject thizA, jint userDataA, jstr ...@@ -91,6 +91,30 @@ static void jniDeviceException(JNIEnv *envA, jobject thizA, jint userDataA, jstr
} }
} }
static void jniLogDebug(JNIEnv *envA, jobject thizA, jstring messageA)
{
Q_UNUSED(thizA);
const char *stringL = envA->GetStringUTFChars(messageA, NULL);
QString logMessage = QString::fromUtf8(stringL);
envA->ReleaseStringUTFChars(messageA, stringL);
if (envA->ExceptionCheck())
envA->ExceptionClear();
qCDebug(AndroidSerialPortLog) << logMessage;
}
static void jniLogWarning(JNIEnv *envA, jobject thizA, jstring messageA)
{
Q_UNUSED(thizA);
const char *stringL = envA->GetStringUTFChars(messageA, NULL);
QString logMessage = QString::fromUtf8(stringL);
envA->ReleaseStringUTFChars(messageA, stringL);
if (envA->ExceptionCheck())
envA->ExceptionClear();
qWarning() << logMessage;
}
void cleanJavaException() void cleanJavaException()
{ {
QAndroidJniEnvironment env; QAndroidJniEnvironment env;
...@@ -116,13 +140,15 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) ...@@ -116,13 +140,15 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
void QSerialPortPrivate::setNativeMethods(void) void QSerialPortPrivate::setNativeMethods(void)
{ {
__android_log_print(ANDROID_LOG_INFO, kJTag, "Registering Native Functions"); qCDebug(AndroidSerialPortLog) << "Registering Native Functions";
// REGISTER THE C++ FUNCTION WITH JNI // REGISTER THE C++ FUNCTION WITH JNI
JNINativeMethod javaMethods[] { JNINativeMethod javaMethods[] {
{"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast<void *>(jniDeviceHasDisconnected)}, {"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast<void *>(jniDeviceHasDisconnected)},
{"nativeDeviceNewData", "(I[B)V", reinterpret_cast<void *>(jniDeviceNewData)}, {"nativeDeviceNewData", "(I[B)V", reinterpret_cast<void *>(jniDeviceNewData)},
{"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast<void *>(jniDeviceException)} {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast<void *>(jniDeviceException)},
{"qgcLogDebug", "(Ljava/lang/String;)V", reinterpret_cast<void *>(jniLogDebug)},
{"qgcLogWarning", "(Ljava/lang/String;)V", reinterpret_cast<void *>(jniLogWarning)}
}; };
QAndroidJniEnvironment jniEnv; QAndroidJniEnvironment jniEnv;
...@@ -133,36 +159,36 @@ void QSerialPortPrivate::setNativeMethods(void) ...@@ -133,36 +159,36 @@ void QSerialPortPrivate::setNativeMethods(void)
jclass objectClass = jniEnv->FindClass(kJniClassName); jclass objectClass = jniEnv->FindClass(kJniClassName);
if(!objectClass) { if(!objectClass) {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Couldn't find class: %s", kJniClassName); qWarning() << "Couldn't find class:" << kJniClassName;
return; return;
} }
jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0])); jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0]));
__android_log_print(ANDROID_LOG_INFO, kJTag, "Native Functions Registered"); if (val < 0) {
qWarning() << "Error registering methods: " << val;
} else {
qCDebug(AndroidSerialPortLog) << "Native Functions Registered";
}
if (jniEnv->ExceptionCheck()) { if (jniEnv->ExceptionCheck()) {
jniEnv->ExceptionDescribe(); jniEnv->ExceptionDescribe();
jniEnv->ExceptionClear(); jniEnv->ExceptionClear();
} }
if (val < 0) {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Error registering methods");
}
} }
bool QSerialPortPrivate::open(QIODevice::OpenMode mode) bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{ {
rwMode = mode; rwMode = mode;
__android_log_print(ANDROID_LOG_INFO, kJTag, "Opening %s", systemLocation.toLatin1().data()); qCDebug(AndroidSerialPortLog) << "Opening" << systemLocation.toLatin1().data();
__android_log_print(ANDROID_LOG_INFO, kJTag, "Calling Java Open");
QAndroidJniObject jnameL = QAndroidJniObject::fromString(systemLocation); QAndroidJniObject jnameL = QAndroidJniObject::fromString(systemLocation);
cleanJavaException(); cleanJavaException();
deviceId = QAndroidJniObject::callStaticMethod<jint>( deviceId = QAndroidJniObject::callStaticMethod<jint>(
kJniClassName, kJniClassName,
"open", "open",
"(Ljava/lang/String;I)I", "(Landroid/content/Context;Ljava/lang/String;I)I",
QtAndroid::androidActivity().object(),
jnameL.object<jstring>(), jnameL.object<jstring>(),
(jint)this); (jint)this);
cleanJavaException(); cleanJavaException();
...@@ -171,20 +197,11 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) ...@@ -171,20 +197,11 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
if (deviceId == BAD_PORT) if (deviceId == BAD_PORT)
{ {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Error opening %s", systemLocation.toLatin1().data()); qWarning() << "Error opening %s" << systemLocation.toLatin1().data();
q_ptr->setError(QSerialPort::DeviceNotFoundError); q_ptr->setError(QSerialPort::DeviceNotFoundError);
return false; return false;
} }
__android_log_print(ANDROID_LOG_INFO, kJTag, "Calling Java getDeviceHandle");
cleanJavaException();
descriptor = QAndroidJniObject::callStaticMethod<jint>(
kJniClassName,
"getDeviceHandle",
"(I)I",
deviceId);
cleanJavaException();
if (rwMode == QIODevice::WriteOnly) if (rwMode == QIODevice::WriteOnly)
stopReadThread(); stopReadThread();
...@@ -196,7 +213,7 @@ void QSerialPortPrivate::close() ...@@ -196,7 +213,7 @@ void QSerialPortPrivate::close()
if (deviceId == BAD_PORT) if (deviceId == BAD_PORT)
return; return;
__android_log_print(ANDROID_LOG_INFO, kJTag, "Closing %s", systemLocation.toLatin1().data()); qCDebug(AndroidSerialPortLog) << "Closing" << systemLocation.toLatin1().data();
cleanJavaException(); cleanJavaException();
jboolean resultL = QAndroidJniObject::callStaticMethod<jboolean>( jboolean resultL = QAndroidJniObject::callStaticMethod<jboolean>(
kJniClassName, kJniClassName,
......
...@@ -49,6 +49,9 @@ ...@@ -49,6 +49,9 @@
#include <QtCore/qstringlist.h> #include <QtCore/qstringlist.h>
#include <QtCore/qthread.h> #include <QtCore/qthread.h>
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY(AndroidSerialPortLog)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
......
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