diff --git a/ground/openpilotgcs/src/libs/qextserialport/src/qextserialport.h b/ground/openpilotgcs/src/libs/qextserialport/src/qextserialport.h index 60d973f41..8d3ac29a6 100644 --- a/ground/openpilotgcs/src/libs/qextserialport/src/qextserialport.h +++ b/ground/openpilotgcs/src/libs/qextserialport/src/qextserialport.h @@ -135,6 +135,7 @@ struct PortSettings #include #include #elif (defined Q_OS_WIN) +#include #include #include #include @@ -308,6 +309,9 @@ class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice #ifdef Q_OS_WIN private slots: void onWinEvent(HANDLE h); + void triggerTxEmpty(); +private: + QTimer fakeTxEmpty; #endif private: diff --git a/ground/openpilotgcs/src/libs/qextserialport/src/win_qextserialport.cpp b/ground/openpilotgcs/src/libs/qextserialport/src/win_qextserialport.cpp index 350dc7533..1fe0ff3ba 100644 --- a/ground/openpilotgcs/src/libs/qextserialport/src/win_qextserialport.cpp +++ b/ground/openpilotgcs/src/libs/qextserialport/src/win_qextserialport.cpp @@ -53,7 +53,6 @@ bool QextSerialPort::open(OpenMode mode) { DWORD dwFlagsAndAttributes = 0; if (queryMode() == QextSerialPort::EventDriven) dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; - QMutexLocker lock(mutex); if (mode == QIODevice::NotOpen) return isOpen(); @@ -95,7 +94,10 @@ bool QextSerialPort::open(OpenMode mode) { } winEventNotifier = new QWinEventNotifier(overlap.hEvent, this); connect(winEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(onWinEvent(HANDLE))); + connect(&fakeTxEmpty,SIGNAL(timeout()),this,SLOT(triggerTxEmpty())); + fakeTxEmpty.start(10000); WaitCommEvent(Win_Handle, &eventMask, &overlap); + } } } else { @@ -111,8 +113,10 @@ is not currently open. void QextSerialPort::close() { QMutexLocker lock(mutex); + fakeTxEmpty.stop(); + disconnect(&fakeTxEmpty,SIGNAL(timeout()),this,SLOT(triggerTxEmpty())); if (isOpen()) { - flush(); + flush(); QIODevice::close(); // mark ourselves as closed CancelIo(Win_Handle); if (CloseHandle(Win_Handle)) @@ -886,4 +890,38 @@ void QextSerialPort::setTimeout(long millisec) { if (queryMode() != QextSerialPort::EventDriven) SetCommTimeouts(Win_Handle, &Win_CommTimeouts); } +/*! +emulates the EV_TXEMPTY system event not present on some BT interfaces +*/ +void QextSerialPort::triggerTxEmpty() +{ + if (bytesToWrite()>500) + { + QMutexLocker lock(mutex); + qint64 totalBytesWritten = 0; + QList overlapsToDelete; + foreach(OVERLAPPED* o, pendingWrites) { + DWORD numBytes = 0; + if (GetOverlappedResult(Win_Handle, o, & numBytes, false)) { + overlapsToDelete.append(o); + totalBytesWritten += numBytes; + } else if( GetLastError() != ERROR_IO_INCOMPLETE ) { + overlapsToDelete.append(o); + qWarning() << "CommEvent overlapped write error:" << GetLastError(); + } + } + if (totalBytesWritten > 0) { + QWriteLocker writelocker(bytesToWriteLock); + _bytesToWrite = 0; + //qDebug()<<"zeroed bytesToWrite"; + } + //qDebug()<<"overlapsToDelete"<hEvent); + delete toDelete; + } + } + +} diff --git a/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp b/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp index 408b9e1ae..e62afb44a 100644 --- a/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp +++ b/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp @@ -165,8 +165,7 @@ void SerialConnection::closeDevice(const QString &deviceName) Q_UNUSED(deviceName); //we have to delete the serial connection we created if (serialHandle){ - serialHandle->close (); - delete(serialHandle); + serialHandle->deleteLater(); serialHandle = NULL; m_deviceOpened = false; }