diff options
Diffstat (limited to 'tools/runonphone/symbianutils/trkdevice.cpp')
-rw-r--r-- | tools/runonphone/symbianutils/trkdevice.cpp | 111 |
1 files changed, 86 insertions, 25 deletions
diff --git a/tools/runonphone/symbianutils/trkdevice.cpp b/tools/runonphone/symbianutils/trkdevice.cpp index b327ab3..bd24300 100644 --- a/tools/runonphone/symbianutils/trkdevice.cpp +++ b/tools/runonphone/symbianutils/trkdevice.cpp @@ -52,6 +52,7 @@ #include <QtCore/QMutex> #include <QtCore/QWaitCondition> #include <QtCore/QSharedPointer> +#include <QtCore/QScopedPointer> #include <QtCore/QMetaType> #ifdef Q_OS_WIN @@ -102,6 +103,11 @@ QString winErrorMessage(unsigned long error) enum { verboseTrk = 0 }; +static inline QString msgAccessingClosedDevice(const QString &msg) +{ + return QString::fromLatin1("Error: Attempt to access device '%1', which is closed.").arg(msg); +} + namespace trk { /////////////////////////////////////////////////////////////////////// @@ -155,10 +161,11 @@ namespace trk { /////////////////////////////////////////////////////////////////////// class TrkWriteQueue -{ +{ Q_DISABLE_COPY(TrkWriteQueue) public: explicit TrkWriteQueue(); + void clear(); // Enqueue messages. void queueTrkMessage(byte code, TrkCallback callback, @@ -208,13 +215,24 @@ TrkWriteQueue::TrkWriteQueue() : { } +void TrkWriteQueue::clear() +{ + m_trkWriteToken = 0; + m_trkWriteBusy = false; + m_trkWriteQueue.clear(); + const int discarded = m_writtenTrkMessages.size(); + m_writtenTrkMessages.clear(); + if (verboseTrk) + qDebug() << "TrkWriteQueue::clear: discarded " << discarded; +} + byte TrkWriteQueue::nextTrkWriteToken() { ++m_trkWriteToken; if (m_trkWriteToken == 0) ++m_trkWriteToken; if (verboseTrk) - qDebug() << "Write token: " << m_trkWriteToken; + qDebug() << "nextTrkWriteToken:" << m_trkWriteToken; return m_trkWriteToken; } @@ -349,7 +367,7 @@ class WriterThread : public QThread { Q_OBJECT Q_DISABLE_COPY(WriterThread) -public: +public: explicit WriterThread(const QSharedPointer<DeviceContext> &context); // Enqueue messages. @@ -357,6 +375,8 @@ public: const QByteArray &data, const QVariant &cookie); void queueTrkInitialPing(); + void clearWriteQueue(); + // Call this from the device read notification with the results. void slotHandleResult(const TrkResult &result); @@ -374,7 +394,7 @@ public slots: private slots: void invokeNoopMessage(const trk::TrkMessage &); -private: +private: bool write(const QByteArray &data, QString *errorMessage); inline int writePendingMessage(); @@ -462,6 +482,7 @@ void WriterThread::terminate() m_waitCondition.wakeAll(); wait(); m_terminate = false; + m_queue.clear(); } #ifdef Q_OS_WIN @@ -561,6 +582,13 @@ void WriterThread::queueTrkMessage(byte code, TrkCallback callback, tryWrite(); } +void WriterThread::clearWriteQueue() +{ + m_dataMutex.lock(); + m_queue.clear(); + m_dataMutex.unlock(); +} + void WriterThread::queueTrkInitialPing() { m_dataMutex.lock(); @@ -592,6 +620,8 @@ class ReaderThreadBase : public QThread Q_DISABLE_COPY(ReaderThreadBase) public: + int bytesPending() const { return m_trkReadBuffer.size(); } + signals: void messageReceived(const trk::TrkResult &result, const QByteArray &rawData); @@ -692,7 +722,7 @@ int WinReaderThread::tryRead() if (!ClearCommError(m_context->device, NULL, &comStat)){ emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError()))); return -7; - } + } const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize))); // Trigger read DWORD bytesRead = 0; @@ -708,7 +738,7 @@ int WinReaderThread::tryRead() if (readError != ERROR_IO_PENDING) { emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError))); return -1; - } + } // Wait for either termination or data const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE); if (wr == WAIT_FAILED) { @@ -783,7 +813,7 @@ private: int m_terminatePipeFileDescriptors[2]; }; -UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) : +UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) : ReaderThreadBase(context) { m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1; @@ -877,8 +907,8 @@ struct TrkDevicePrivate TrkDevicePrivate(); QSharedPointer<DeviceContext> deviceContext; - QSharedPointer<WriterThread> writerThread; - QSharedPointer<ReaderThread> readerThread; + QScopedPointer<WriterThread> writerThread; + QScopedPointer<ReaderThread> readerThread; QByteArray trkReadBuffer; int verbose; @@ -917,14 +947,14 @@ TrkDevice::~TrkDevice() bool TrkDevice::open(QString *errorMessage) { - if (d->verbose) + if (d->verbose || verboseTrk) qDebug() << "Opening" << port() << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + if (isOpen()) + return true; if (d->port.isEmpty()) { *errorMessage = QLatin1String("Internal error: No port set on TrkDevice"); return false; } - - close(); #ifdef Q_OS_WIN const QString fullPort = QLatin1String("\\\\.\\") + d->port; d->deviceContext->device = CreateFile(reinterpret_cast<const WCHAR*>(fullPort.utf16()), @@ -975,7 +1005,7 @@ bool TrkDevice::open(QString *errorMessage) return false; } #endif - d->readerThread = QSharedPointer<ReaderThread>(new ReaderThread(d->deviceContext)); + d->readerThread.reset(new ReaderThread(d->deviceContext)); connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), Qt::QueuedConnection); connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)), @@ -983,18 +1013,22 @@ bool TrkDevice::open(QString *errorMessage) Qt::QueuedConnection); d->readerThread->start(); - d->writerThread = QSharedPointer<WriterThread>(new WriterThread(d->deviceContext)); + d->writerThread.reset(new WriterThread(d->deviceContext)); connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), - Qt::QueuedConnection); - d->writerThread->start(); + Qt::QueuedConnection); + d->writerThread->start(); - if (d->verbose) - qDebug() << "Opened" << d->port; + if (d->verbose || verboseTrk) + qDebug() << "Opened" << d->port << d->readerThread.data() << d->writerThread.data(); return true; } void TrkDevice::close() { + if (verboseTrk) + qDebug() << "close" << d->port << " is open: " << isOpen() + << " read pending " << (d->readerThread.isNull() ? 0 : d->readerThread->bytesPending()) + << sender(); if (!isOpen()) return; if (d->readerThread) @@ -1010,6 +1044,7 @@ void TrkDevice::close() #else d->deviceContext->file.close(); #endif + if (d->verbose) emitLogMessage("Close"); } @@ -1030,6 +1065,8 @@ QString TrkDevice::port() const void TrkDevice::setPort(const QString &p) { + if (verboseTrk) + qDebug() << "setPort" << p; d->port = p; } @@ -1045,6 +1082,8 @@ bool TrkDevice::serialFrame() const void TrkDevice::setSerialFrame(bool f) { + if (verboseTrk) + qDebug() << "setSerialFrame" << f; d->deviceContext->serialFrame = f; } @@ -1060,12 +1099,14 @@ void TrkDevice::setVerbose(int b) void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) { - d->writerThread->slotHandleResult(result); - if (d->verbose > 1) - qDebug() << "Received: " << result.toString(); - emit messageReceived(result); - if (!rawData.isEmpty()) - emit rawDataReceived(rawData); + if (isOpen()) { // Might receive bytes after closing due to queued connections. + d->writerThread->slotHandleResult(result); + if (d->verbose > 1) + qDebug() << "Received: " << result.toString(); + emit messageReceived(result); + if (!rawData.isEmpty()) + emit rawDataReceived(rawData); + } } void TrkDevice::emitError(const QString &s) @@ -1075,15 +1116,27 @@ void TrkDevice::emitError(const QString &s) emit error(s); } +void TrkDevice::clearWriteQueue() +{ + if (isOpen()) + d->writerThread->clearWriteQueue(); +} + void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, const QByteArray &data, const QVariant &cookie) { + if (!isOpen()) { + emitError(msgAccessingClosedDevice(d->port)); + return; + } if (!d->writerThread.isNull()) { if (d->verbose > 1) { - QByteArray msg = "Sending: "; + QByteArray msg = "Sending: 0x"; msg += QByteArray::number(code, 16); msg += ": "; msg += stringFromArray(data).toLatin1(); + if (cookie.isValid()) + msg += " Cookie: " + cookie.toString().toLatin1(); qDebug("%s", msg.data()); } d->writerThread->queueTrkMessage(code, callback, data, cookie); @@ -1092,12 +1145,20 @@ void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, void TrkDevice::sendTrkInitialPing() { + if (!isOpen()) { + emitError(msgAccessingClosedDevice(d->port)); + return; + } if (!d->writerThread.isNull()) d->writerThread->queueTrkInitialPing(); } bool TrkDevice::sendTrkAck(byte token) { + if (!isOpen()) { + emitError(msgAccessingClosedDevice(d->port)); + return false; + } if (d->writerThread.isNull()) return false; // The acknowledgement must not be queued! |