diff --git a/android/libs/d2xx.jar b/android/libs/d2xx.jar new file mode 100755 index 0000000000000000000000000000000000000000..6610490d14a9a033ec212e5bb7febdd820756146 Binary files /dev/null and b/android/libs/d2xx.jar differ diff --git a/android/res/xml/device_filter.xml b/android/res/xml/device_filter.xml index a149a80b508d8f8978a9fdd66bfedd4b78ca4046..782fae8dd7e17709718b824ace9fa92e9479b52b 100644 --- a/android/res/xml/device_filter.xml +++ b/android/res/xml/device_filter.xml @@ -1,40 +1,6 @@ - + - - - - - - - - - - - - - - - - - - - - diff --git a/android/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java b/android/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java index ad3627ff38a75a50b71167ddf50f50b4ee5b1b51..5ca03607460a0c38844ebe777bebda38cd0a1f8e 100644 --- a/android/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java +++ b/android/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java @@ -18,6 +18,10 @@ * Project home page: http://code.google.com/p/usb-serial-for-android/ */ +// IMPORTANT NOTE: +// This code has been modified from the original source. It now uses the FTDI driver provided by +// ftdichip.com to communicate with an FTDI device. The previous code did not work with all FTDI +// devices. package com.hoho.android.usbserial.driver; import android.hardware.usb.UsbConstants; @@ -27,12 +31,16 @@ import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbRequest; import android.util.Log; +import com.ftdi.j2xx.D2xxManager; +import com.ftdi.j2xx.FT_Device; import java.io.IOException; import java.nio.ByteBuffer; import java.util.LinkedHashMap; import java.util.Map; +import org.qgroundcontrol.qgchelper.UsbDeviceJNI; + /** * A {@link CommonUsbSerialDriver} implementation for a variety of FTDI devices *

@@ -167,6 +175,8 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver { */ private static final boolean ENABLE_ASYNC_READS = false; + FT_Device m_ftDev; + /** * Filter FTDI status bytes from buffer * @param src The source buffer (which contains status bytes) @@ -219,261 +229,140 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver { @Override public void open() throws IOException { - boolean opened = false; + D2xxManager ftD2xx = null; try { - for (int i = 0; i < mDevice.getInterfaceCount(); i++) { - if (mConnection.claimInterface(mDevice.getInterface(i), true)) { - Log.d(TAG, "claimInterface " + i + " SUCCESS"); - } else { - throw new IOException("Error claiming interface " + i); - } - } - reset(); - opened = true; + ftD2xx = D2xxManager.getInstance(UsbDeviceJNI.m_context); + } catch (D2xxManager.D2xxException ex) { + UsbDeviceJNI.qgcLogDebug("D2xxManager.getInstance threw exception: " + ex.getMessage()); + } + + if (ftD2xx == null) { + String errMsg = "Unable to retrieve D2xxManager instance."; + UsbDeviceJNI.qgcLogWarning(errMsg); + throw new IOException(errMsg); + } + UsbDeviceJNI.qgcLogDebug("Opened D2xxManager"); + + int DevCount = ftD2xx.createDeviceInfoList(UsbDeviceJNI.m_context); + UsbDeviceJNI.qgcLogDebug("Found " + DevCount + " ftdi devices."); + if (DevCount < 1) { + throw new IOException("No FTDI Devices found"); + } + + m_ftDev = null; + try { + m_ftDev = ftD2xx.openByIndex(UsbDeviceJNI.m_context, 0); + } catch (NullPointerException e) { + UsbDeviceJNI.qgcLogDebug("ftD2xx.openByIndex exception: " + e.getMessage()); } finally { - if (!opened) { - close(); + if (m_ftDev == null) { + throw new IOException("No FTDI Devices found"); } } + UsbDeviceJNI.qgcLogDebug("Opened FTDI device."); } @Override public void close() { - mConnection.close(); + if (m_ftDev != null) { + try { + m_ftDev.close(); + } catch (Exception e) { + UsbDeviceJNI.qgcLogWarning("close exception: " + e.getMessage()); + } + m_ftDev = null; + } } @Override public int read(byte[] dest, int timeoutMillis) throws IOException { - final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0); - - if (ENABLE_ASYNC_READS) { - final int readAmt; - synchronized (mReadBufferLock) { - // mReadBuffer is only used for maximum read size. - readAmt = Math.min(dest.length, mReadBuffer.length); - } - - final UsbRequest request = new UsbRequest(); - request.initialize(mConnection, endpoint); - - final ByteBuffer buf = ByteBuffer.wrap(dest); - if (!request.queue(buf, readAmt)) { - throw new IOException("Error queueing request."); - } - - final UsbRequest response = mConnection.requestWait(); - if (response == null) { - throw new IOException("Null response"); - } - - final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH; - if (payloadBytesRead > 0) { - return payloadBytesRead; - } else { - return 0; - } - } else { - final int totalBytesRead; - - synchronized (mReadBufferLock) { - final int readAmt = Math.min(dest.length, mReadBuffer.length); - totalBytesRead = mConnection.bulkTransfer(endpoint, mReadBuffer, - readAmt, timeoutMillis); - - if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { - throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); - } - - return filterStatusBytes(mReadBuffer, dest, totalBytesRead, endpoint.getMaxPacketSize()); + int totalBytesRead = 0; + int bytesAvailable = m_ftDev.getQueueStatus(); + + if (bytesAvailable > 0) { + bytesAvailable = Math.min(4096, bytesAvailable); + try { + totalBytesRead = m_ftDev.read(dest, bytesAvailable, timeoutMillis); + } catch (NullPointerException e) { + final String errorMsg = "Error reading: " + e.getMessage(); + UsbDeviceJNI.qgcLogWarning(errorMsg); + throw new IOException(errorMsg, e); } } + + return totalBytesRead; } @Override public int write(byte[] src, int timeoutMillis) throws IOException { - final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(1); - int offset = 0; - - while (offset < src.length) { - final int writeLength; - final int amtWritten; - - synchronized (mWriteBufferLock) { - final byte[] writeBuffer; - - writeLength = Math.min(src.length - offset, mWriteBuffer.length); - if (offset == 0) { - writeBuffer = src; - } else { - // bulkTransfer does not support offsets, make a copy. - System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); - writeBuffer = mWriteBuffer; - } - - amtWritten = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength, - timeoutMillis); - } - - if (amtWritten <= 0) { - throw new IOException("Error writing " + writeLength - + " bytes at offset " + offset + " length=" + src.length); - } - - //Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength); - offset += amtWritten; + try { + m_ftDev.write(src); + return src.length; + } catch (Exception e) { + UsbDeviceJNI.qgcLogWarning("Error writing: " + e.getMessage()); } - return offset; + return 0; } private int setBaudRate(int baudRate) throws IOException { - long[] vals = convertBaudrate(baudRate); - long actualBaudrate = vals[0]; - long index = vals[1]; - long value = vals[2]; - int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, - SIO_SET_BAUD_RATE_REQUEST, (int) value, (int) index, - null, 0, USB_WRITE_TIMEOUT_MILLIS); - if (result != 0) { - throw new IOException("Setting baudrate failed: result=" + result); + try { + m_ftDev.setBaudRate(baudRate); + return baudRate; + } catch (Exception e) { + UsbDeviceJNI.qgcLogWarning("Error setting baud rate: " + e.getMessage()); } - return (int) actualBaudrate; + return 0; } @Override - public void setParameters(int baudRate, int dataBits, int stopBits, int parity) - throws IOException { + public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException { setBaudRate(baudRate); - int config = dataBits; - - switch (parity) { - case PARITY_NONE: - config |= (0x00 << 8); - break; - case PARITY_ODD: - config |= (0x01 << 8); - break; - case PARITY_EVEN: - config |= (0x02 << 8); - break; - case PARITY_MARK: - config |= (0x03 << 8); - break; - case PARITY_SPACE: - config |= (0x04 << 8); - break; - default: - throw new IllegalArgumentException("Unknown parity value: " + parity); + switch (dataBits) { + case 7: + dataBits = D2xxManager.FT_DATA_BITS_7; + break; + case 8: + default: + dataBits = D2xxManager.FT_DATA_BITS_8; + break; } switch (stopBits) { - case STOPBITS_1: - config |= (0x00 << 11); - break; - case STOPBITS_1_5: - config |= (0x01 << 11); - break; - case STOPBITS_2: - config |= (0x02 << 11); - break; - default: - throw new IllegalArgumentException("Unknown stopBits value: " + stopBits); - } - - int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, - SIO_SET_DATA_REQUEST, config, 0 /* index */, - null, 0, USB_WRITE_TIMEOUT_MILLIS); - if (result != 0) { - throw new IOException("Setting parameters failed: result=" + result); + default: + case 0: + stopBits = D2xxManager.FT_STOP_BITS_1; + break; + case 1: + stopBits = D2xxManager.FT_STOP_BITS_2; + break; } - } - private long[] convertBaudrate(int baudrate) { - // TODO(mikey): Braindead transcription of libfti method. Clean up, - // using more idiomatic Java where possible. - int divisor = 24000000 / baudrate; - int bestDivisor = 0; - int bestBaud = 0; - int bestBaudDiff = 0; - int fracCode[] = { - 0, 3, 2, 4, 1, 5, 6, 7 - }; - - for (int i = 0; i < 2; i++) { - int tryDivisor = divisor + i; - int baudEstimate; - int baudDiff; - - if (tryDivisor <= 8) { - // Round up to minimum supported divisor - tryDivisor = 8; - } else if (mType != DeviceType.TYPE_AM && tryDivisor < 12) { - // BM doesn't support divisors 9 through 11 inclusive - tryDivisor = 12; - } else if (divisor < 16) { - // AM doesn't support divisors 9 through 15 inclusive - tryDivisor = 16; - } else { - if (mType == DeviceType.TYPE_AM) { - // TODO - } else { - if (tryDivisor > 0x1FFFF) { - // Round down to maximum supported divisor value (for - // BM) - tryDivisor = 0x1FFFF; - } - } - } - - // Get estimated baud rate (to nearest integer) - baudEstimate = (24000000 + (tryDivisor / 2)) / tryDivisor; - - // Get absolute difference from requested baud rate - if (baudEstimate < baudrate) { - baudDiff = baudrate - baudEstimate; - } else { - baudDiff = baudEstimate - baudrate; - } - - if (i == 0 || baudDiff < bestBaudDiff) { - // Closest to requested baud rate so far - bestDivisor = tryDivisor; - bestBaud = baudEstimate; - bestBaudDiff = baudDiff; - if (baudDiff == 0) { - // Spot on! No point trying - break; - } - } - } - - // Encode the best divisor value - long encodedDivisor = (bestDivisor >> 3) | (fracCode[bestDivisor & 7] << 14); - // Deal with special cases for encoded value - if (encodedDivisor == 1) { - encodedDivisor = 0; // 3000000 baud - } else if (encodedDivisor == 0x4001) { - encodedDivisor = 1; // 2000000 baud (BM only) + switch (parity) { + default: + case 0: + parity = D2xxManager.FT_PARITY_NONE; + break; + case 1: + parity = D2xxManager.FT_PARITY_ODD; + break; + case 2: + parity = D2xxManager.FT_PARITY_EVEN; + break; + case 3: + parity = D2xxManager.FT_PARITY_MARK; + break; + case 4: + parity = D2xxManager.FT_PARITY_SPACE; + break; } - // Split into "value" and "index" values - long value = encodedDivisor & 0xFFFF; - long index; - if (mType == DeviceType.TYPE_2232C || mType == DeviceType.TYPE_2232H - || mType == DeviceType.TYPE_4232H) { - index = (encodedDivisor >> 8) & 0xffff; - index &= 0xFF00; - index |= 0 /* TODO mIndex */; - } else { - index = (encodedDivisor >> 16) & 0xffff; + try { + m_ftDev.setDataCharacteristics((byte)dataBits, (byte)stopBits, (byte)parity); + } catch (Exception e) { + UsbDeviceJNI.qgcLogWarning("Error setDataCharacteristics: " + e.getMessage()); } - - // Return the nearest baud rate - return new long[] { - bestBaud, index, value - }; } - @Override public boolean getCD() throws IOException { return false; @@ -515,18 +404,22 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver { @Override public boolean purgeHwBuffers(boolean purgeReadBuffers, boolean purgeWriteBuffers) throws IOException { if (purgeReadBuffers) { - int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, - SIO_RESET_PURGE_RX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS); - if (result != 0) { - throw new IOException("Flushing RX failed: result=" + result); + try { + m_ftDev.purge(D2xxManager.FT_PURGE_RX); + } catch (Exception e) { + String errMsg = "Error purgeHwBuffers(RX): "+ e.getMessage(); + UsbDeviceJNI.qgcLogWarning(errMsg); + throw new IOException(errMsg); } } if (purgeWriteBuffers) { - int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, - SIO_RESET_PURGE_TX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS); - if (result != 0) { - throw new IOException("Flushing RX failed: result=" + result); + try { + m_ftDev.purge(D2xxManager.FT_PURGE_TX); + } catch (Exception e) { + String errMsg = "Error purgeHwBuffers(TX): " + e.getMessage(); + UsbDeviceJNI.qgcLogWarning(errMsg); + throw new IOException(errMsg); } } diff --git a/android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java b/android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java index 2e25a761e9c27488479ce383a7ee48bb6227413a..b689ccc7c28e1b47c05c41a016bfe9567ffcdd5a 100644 --- a/android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java +++ b/android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java @@ -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 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 supportedDevices) { + return supportedDevices.containsKey(usbDevice.getVendorId()); } - } diff --git a/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java b/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java index 6520ebb6b9258722fa168a19aa9743b9e7820ff8..183d5c25786fa78a4feb9a0fedb255207373c442 100644 --- a/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java +++ b/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java @@ -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; } } diff --git a/libs/qtandroidserialport/src/qserialport_android.cpp b/libs/qtandroidserialport/src/qserialport_android.cpp index 675805a459572798b2cd078cc728e82d17918a57..9e8060c03dae3d8dd006564d78bb0ed3628c2a2f 100644 --- a/libs/qtandroidserialport/src/qserialport_android.cpp +++ b/libs/qtandroidserialport/src/qserialport_android.cpp @@ -46,10 +46,10 @@ #include #include -#include - #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(jniDeviceHasDisconnected)}, - {"nativeDeviceNewData", "(I[B)V", reinterpret_cast(jniDeviceNewData)}, - {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast(jniDeviceException)} + {"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast(jniDeviceHasDisconnected)}, + {"nativeDeviceNewData", "(I[B)V", reinterpret_cast(jniDeviceNewData)}, + {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast(jniDeviceException)}, + {"qgcLogDebug", "(Ljava/lang/String;)V", reinterpret_cast(jniLogDebug)}, + {"qgcLogWarning", "(Ljava/lang/String;)V", reinterpret_cast(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( kJniClassName, "open", - "(Ljava/lang/String;I)I", + "(Landroid/content/Context;Ljava/lang/String;I)I", + QtAndroid::androidActivity().object(), jnameL.object(), (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( - 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( kJniClassName, diff --git a/libs/qtandroidserialport/src/qserialport_android_p.h b/libs/qtandroidserialport/src/qserialport_android_p.h index c10c41cc4a29cd61b0d9b6213a9abca9821fd695..4778774d29689ad99550cd414a87c816eaa81ff6 100644 --- a/libs/qtandroidserialport/src/qserialport_android_p.h +++ b/libs/qtandroidserialport/src/qserialport_android_p.h @@ -49,6 +49,9 @@ #include #include +#include "QGCLoggingCategory.h" + +Q_DECLARE_LOGGING_CATEGORY(AndroidSerialPortLog) QT_BEGIN_NAMESPACE