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"?>
<resources>
<!-- Everything -->
<!-- Allow anything connected -->
<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>
......@@ -18,6 +18,10 @@
* 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;
import android.hardware.usb.UsbDevice;
......@@ -230,21 +234,7 @@ public enum UsbSerialProber {
* @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 productId = usbDevice.getProductId();
for (int supportedProductId : supportedProducts) {
if (productId == supportedProductId) {
return true;
}
}
return false;
private static boolean testIfSupported(final UsbDevice usbDevice, final Map<Integer, int[]> supportedDevices) {
return supportedDevices.containsKey(usbDevice.getVendorId());
}
}
......@@ -68,6 +68,8 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
private static TextToSpeech m_tts;
private static PowerManager.WakeLock m_wl;
public static Context m_context;
private final static UsbIoManager.Listener m_Listener =
new UsbIoManager.Listener()
{
......@@ -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 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.
......@@ -252,7 +258,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
tempL = tempL + Integer.toString(deviceL.getVendorId()) + ":";
listL[countL] = tempL;
countL++;
//Log.i(TAG, "Found " + tempL);
qgcLogDebug("Found " + tempL);
}
}
......@@ -273,11 +279,13 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
// 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;
Log.i(TAG, "Getting device list");
m_context = parentContext;
//qgcLogDebug("Getting device list");
if (!getCurrentDevices())
return BAD_PORT;
......@@ -366,7 +374,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
m_ioManager.remove(idL);
}
Log.e(TAG, "Port open exception");
qgcLogWarning("Port open exception: " + exA.getMessage());
return BAD_PORT;
}
}
......
......@@ -46,10 +46,10 @@
#include <QtAndroidExtras/QtAndroidExtras>
#include <QtAndroidExtras/QAndroidJniObject>
#include <android/log.h>
#include "qserialport_android_p.h"
QGC_LOGGING_CATEGORY(AndroidSerialPortLog, "AndroidSerialPortLog")
QT_BEGIN_NAMESPACE
#define BAD_PORT 0
......@@ -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()
{
QAndroidJniEnvironment env;
......@@ -116,13 +140,15 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
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
JNINativeMethod javaMethods[] {
{"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast<void *>(jniDeviceHasDisconnected)},
{"nativeDeviceNewData", "(I[B)V", reinterpret_cast<void *>(jniDeviceNewData)},
{"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast<void *>(jniDeviceException)}
{"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast<void *>(jniDeviceHasDisconnected)},
{"nativeDeviceNewData", "(I[B)V", reinterpret_cast<void *>(jniDeviceNewData)},
{"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;
......@@ -133,36 +159,36 @@ void QSerialPortPrivate::setNativeMethods(void)
jclass objectClass = jniEnv->FindClass(kJniClassName);
if(!objectClass) {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Couldn't find class: %s", kJniClassName);
qWarning() << "Couldn't find class:" << kJniClassName;
return;
}
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()) {
jniEnv->ExceptionDescribe();
jniEnv->ExceptionClear();
}
if (val < 0) {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Error registering methods");
}
}
bool QSerialPortPrivate::open(QIODevice::OpenMode 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);
cleanJavaException();
deviceId = QAndroidJniObject::callStaticMethod<jint>(
kJniClassName,
"open",
"(Ljava/lang/String;I)I",
"(Landroid/content/Context;Ljava/lang/String;I)I",
QtAndroid::androidActivity().object(),
jnameL.object<jstring>(),
(jint)this);
cleanJavaException();
......@@ -171,20 +197,11 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
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);
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)
stopReadThread();
......@@ -196,7 +213,7 @@ void QSerialPortPrivate::close()
if (deviceId == BAD_PORT)
return;
__android_log_print(ANDROID_LOG_INFO, kJTag, "Closing %s", systemLocation.toLatin1().data());
qCDebug(AndroidSerialPortLog) << "Closing" << systemLocation.toLatin1().data();
cleanJavaException();
jboolean resultL = QAndroidJniObject::callStaticMethod<jboolean>(
kJniClassName,
......
......@@ -49,6 +49,9 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qthread.h>
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY(AndroidSerialPortLog)
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