1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-19 09:54:15 +01:00

Fix for bluetooth modules hanging. Turns out certain HW don't implement the EV_TXEMPTY system event. Hack was to create a timer which triggers a fake event every 10secs. It checks the bytestosend value so it shouldn't have any effect on full compliant HW.

This commit is contained in:
zedamota 2011-07-24 22:43:59 +01:00
parent 056db1cdda
commit ba8985721c
3 changed files with 45 additions and 4 deletions

View File

@ -135,6 +135,7 @@ struct PortSettings
#include <sys/select.h>
#include <QSocketNotifier>
#elif (defined Q_OS_WIN)
#include <QTimer>
#include <windows.h>
#include <QThread>
#include <QReadWriteLock>
@ -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:

View File

@ -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<OVERLAPPED*> 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"<<overlapsToDelete.count();
foreach(OVERLAPPED* o, overlapsToDelete) {
OVERLAPPED *toDelete = pendingWrites.takeAt(pendingWrites.indexOf(o));
CloseHandle(toDelete->hEvent);
delete toDelete;
}
}
}

View File

@ -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;
}