summaryrefslogtreecommitdiffstats
path: root/tools/runonphone/symbianutils/trkdevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/runonphone/symbianutils/trkdevice.cpp')
-rw-r--r--tools/runonphone/symbianutils/trkdevice.cpp111
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!