summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorTom Sutcliffe <ext-thomas.1.sutcliffe@nokia.com>2011-02-07 14:14:57 +0100
committerPawel Polanski <pawel.3.polanski@nokia.com>2011-02-08 09:18:45 +0100
commita0349893500530f5769fae7b4bbc9a1edea22260 (patch)
treeb914293b405821af10b4f632c4da5dcbb87d0b0a /src/shared
parent31b352d2199ebbbcc7d86d9d0040c5ec8756617d (diff)
downloadqt-creator-a0349893500530f5769fae7b4bbc9a1edea22260.tar.gz
Sharing TcfTrkDevice connections between multiple clients
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/symbianutils/codadevice.cpp51
-rw-r--r--src/shared/symbianutils/codadevice.h4
-rw-r--r--src/shared/symbianutils/symbiandevicemanager.cpp88
-rw-r--r--src/shared/symbianutils/symbiandevicemanager.h20
-rw-r--r--src/shared/symbianutils/virtualserialdevice_posix.cpp13
5 files changed, 89 insertions, 87 deletions
diff --git a/src/shared/symbianutils/codadevice.cpp b/src/shared/symbianutils/codadevice.cpp
index c01a798293..a8a77d06d3 100644
--- a/src/shared/symbianutils/codadevice.cpp
+++ b/src/shared/symbianutils/codadevice.cpp
@@ -43,7 +43,7 @@
#include <QtCore/QDateTime>
#include <QtCore/QFileInfo>
-enum { debug = 1 };
+enum { debug = 0 };
static const char tcpMessageTerminatorC[] = "\003\001";
@@ -60,15 +60,18 @@ static const char locatorAnswerC[] = "E\0Locator\0Hello\0[\"Locator\"]";
static const unsigned serialChunkLength = 0x400; // 1K max USB router
static const int maxSerialMessageLength = 0x10000; // given chunking scheme
+static const char validProtocolIdStart = (char)0x90;
+static const char validProtocolIdEnd = (char)0x95;
+static const char codaProtocolId = (char)0x92;
static const unsigned char serialChunkingStart = 0xfe;
static const unsigned char serialChunkingContinuation = 0x0;
enum { SerialChunkHeaderSize = 2 };
// Create USB router frame
-static inline void encodeSerialFrame(const QByteArray &data, QByteArray *target)
+static inline void encodeSerialFrame(const QByteArray &data, QByteArray *target, char protocolId)
{
target->append(char(0x01));
- target->append(char(0x92)); // CODA serial message ID
+ target->append(protocolId);
appendShort(target, ushort(data.size()), trk::BigEndian);
target->append(data);
}
@@ -76,14 +79,14 @@ static inline void encodeSerialFrame(const QByteArray &data, QByteArray *target)
// Split in chunks of 1K according to CODA protocol chunking
static inline QByteArray encodeUsbSerialMessage(const QByteArray &dataIn)
{
- // Reserve 2 header bytes
+ // Reserve 2 header bytes
static const int chunkSize = serialChunkLength - SerialChunkHeaderSize;
const int size = dataIn.size();
QByteArray frame;
// Do we need to split?
if (size < chunkSize) { // Nope, all happy.
frame.reserve(size + 4);
- encodeSerialFrame(dataIn, &frame);
+ encodeSerialFrame(dataIn, &frame, codaProtocolId);
return frame;
}
// Split.
@@ -102,7 +105,7 @@ static inline QByteArray encodeUsbSerialMessage(const QByteArray &dataIn)
chunk.append(char(static_cast<unsigned char>(c))); // Avoid any signedness issues.
const int chunkEnd = qMin(pos + chunkSize, size);
chunk.append(dataIn.mid(pos, chunkEnd - pos));
- encodeSerialFrame(chunk, &frame);
+ encodeSerialFrame(chunk, &frame, codaProtocolId);
pos = chunkEnd;
}
if (debug > 1)
@@ -471,26 +474,24 @@ void CodaDevice::slotDeviceReadyRead()
// Find a serial header in input stream '0x1', '0x92', 'lenH', 'lenL'
// and return message position and size.
-QPair<int, int> TcfTrkDevice::findSerialHeader(QByteArray &in)
+QPair<int, int> CodaDevice::findSerialHeader(QByteArray &in)
{
- const char header1 = 0x1;
- const char header2 = char(0x92);
- const char header2tracecore = char(0x91);
- // Header should in theory always be at beginning of
+ static const char header1 = 0x1;
+ // Header should in theory always be at beginning of
// buffer. Warn if there are bogus data in-between.
while (in.size() >= 4) {
- if (in.at(0) == header1 && in.at(1) == header2) {
+ if (in.at(0) == header1 && in.at(1) == codaProtocolId) {
// Good packet
const int length = trk::extractShort(in.constData() + 2);
return QPair<int, int>(4, length);
- } else if (in.at(0) == header1 && in.at(1) == header2tracecore) {
+ } else if (in.at(0) == header1 && in.at(1) >= validProtocolIdStart && in.at(1) <= validProtocolIdEnd) {
// We recognise it but it's not a TCF message - emit it for any interested party to handle
const int length = trk::extractShort(in.constData() + 2);
if (4 + length <= in.size()) {
// We have all the data
QByteArray data(in.mid(4, length));
- emit traceCoreEvent(data);
+ emit unknownEvent(in.at(1), data);
in.remove(0, 4+length);
// and continue
} else {
@@ -504,7 +505,6 @@ QPair<int, int> TcfTrkDevice::findSerialHeader(QByteArray &in)
QByteArray bad = in.mid(0, nextHeader);
qWarning("Bogus data received on serial line: %s\n"
"Frame Header at: %d", qPrintable(trk::stringFromArray(bad)), nextHeader);
- d->m_device->write(bad); // Backatcha - TOMSCI TESTING
in.remove(0, bad.length());
// and continue
}
@@ -787,9 +787,6 @@ void CodaDevice::sendSerialPing(bool pingOnly)
if (!checkOpen())
return;
- dumpObjectInfo();
- d->m_device->dumpObjectInfo();
-
d->m_serialPingOnly = pingOnly;
setSerialFrame(true);
writeMessage(QByteArray(serialPingC, qstrlen(serialPingC)), false);
@@ -869,6 +866,24 @@ void CodaDevice::writeMessage(QByteArray data, bool ensureTerminating0)
as->flush();
}
+void CodaDevice::writeCustomData(char protocolId, const QByteArray &data)
+{
+ if (!checkOpen())
+ return;
+
+ if (!d->m_serialFrame) {
+ qWarning("Ignoring request to send data to non-serial CodaDevice");
+ return;
+ }
+ if (data.length() > 0xFFFF) {
+ qWarning("Ignoring request to send too large packet, of size %d", data.length());
+ return;
+ }
+ QByteArray framedData;
+ encodeSerialFrame(data, &framedData, protocolId);
+ device()->write(framedData);
+}
+
void CodaDevice::checkSendQueue()
{
// Fire off messages or invoke noops until a message with reply is found
diff --git a/src/shared/symbianutils/codadevice.h b/src/shared/symbianutils/codadevice.h
index a52c8d8614..f2e029be91 100644
--- a/src/shared/symbianutils/codadevice.h
+++ b/src/shared/symbianutils/codadevice.h
@@ -360,6 +360,8 @@ public:
// Settings
void sendSettingsEnableLogCommand();
+ void writeCustomData(char protocolId, const QByteArray &aData);
+
static QByteArray parseMemoryGet(const CodaCommandResult &r);
static QVector<QByteArray> parseRegisterGetChildren(const CodaCommandResult &r);
static CodaStatResponse parseStat(const CodaCommandResult &r);
@@ -367,7 +369,7 @@ public:
signals:
void genericTcfEvent(int service, const QByteArray &name, const QVector<JsonValue> &value);
void tcfEvent(const Coda::CodaEvent &knownEvent);
- void traceCoreEvent(const QByteArray& data);
+ void unknownEvent(uchar protocolId, const QByteArray& data);
void serialPong(const QString &codaVersion);
void logMessage(const QString &);
diff --git a/src/shared/symbianutils/symbiandevicemanager.cpp b/src/shared/symbianutils/symbiandevicemanager.cpp
index 61c976126f..c36bab9995 100644
--- a/src/shared/symbianutils/symbiandevicemanager.cpp
+++ b/src/shared/symbianutils/symbiandevicemanager.cpp
@@ -33,7 +33,7 @@
#include "symbiandevicemanager.h"
#include "trkdevice.h"
-#include "tcftrkdevice.h"
+#include "codadevice.h"
#include "virtualserialdevice.h"
#include <QtCore/QSettings>
@@ -73,7 +73,7 @@ public:
DeviceCommunicationType type;
QSharedPointer<trk::TrkDevice> device;
- QSharedPointer<tcftrk::TcfTrkDevice> tcfdevice;
+ QSharedPointer<Coda::CodaDevice> codaDevice;
bool deviceAcquired;
};
@@ -85,14 +85,11 @@ SymbianDeviceData::SymbianDeviceData() :
bool SymbianDeviceData::isOpen() const
{
- if (device) {
- // TRK device
+ if (device)
return device->isOpen();
- } else if (tcfdevice) {
- return tcfdevice->device()->isOpen();
- } else {
- return false;
- }
+ if (codaDevice)
+ return codaDevice->device()->isOpen();
+ return false;
}
SymbianDeviceData::~SymbianDeviceData()
@@ -110,8 +107,10 @@ void SymbianDeviceData::forcedClose()
if (deviceAcquired)
qWarning("Device on '%s' unplugged while an operation is in progress.",
qPrintable(portName));
- if (device) device->close();
- else tcfdevice->device()->close();
+ if (device)
+ device->close();
+ else
+ codaDevice->device()->close();
}
}
@@ -278,12 +277,12 @@ struct SymbianDeviceManagerPrivate {
class QConstructTcfPortEvent : public QEvent
{
public:
- QConstructTcfPortEvent(QEvent::Type eventId, const QString &portName, TcfTrkDevicePtr *device, QWaitCondition *waiter) :
+ QConstructTcfPortEvent(QEvent::Type eventId, const QString &portName, CodaDevicePtr *device, QWaitCondition *waiter) :
QEvent(eventId), m_portName(portName), m_device(device), m_waiter(waiter)
{}
QString m_portName;
- TcfTrkDevicePtr* m_device;
+ CodaDevicePtr* m_device;
QWaitCondition *m_waiter;
};
@@ -353,7 +352,7 @@ SymbianDeviceManager::TrkDevicePtr
return rc;
}
-TcfTrkDevicePtr SymbianDeviceManager::getTcfPort(const QString &port)
+CodaDevicePtr SymbianDeviceManager::getTcfPort(const QString &port)
{
ensureInitialized();
const int idx = findByPortName(port);
@@ -361,16 +360,16 @@ TcfTrkDevicePtr SymbianDeviceManager::getTcfPort(const QString &port)
qWarning("Attempt to acquire device '%s' that does not exist.", qPrintable(port));
if (debug)
qDebug() << *this;
- return TcfTrkDevicePtr();
+ return CodaDevicePtr();
}
SymbianDevice& device = d->m_devices[idx];
if (device.m_data->device) {
qWarning("Attempting to open a port '%s' that is configured for TRK!", qPrintable(port));
- return TcfTrkDevicePtr();
+ return CodaDevicePtr();
}
- TcfTrkDevicePtr& devicePtr = device.m_data->tcfdevice;
- if (devicePtr.isNull()) {
- // Check we instanciate in the correct thread - we can't afford to create the TcfTrkDevice (and more specifically, open the VirtualSerialDevice) in a thread that isn't guaranteed to be long-lived.
+ CodaDevicePtr& devicePtr = device.m_data->codaDevice;
+ if (devicePtr.isNull() || !devicePtr->device()->isOpen()) {
+ // Check we instanciate in the correct thread - we can't afford to create the CodaDevice (and more specifically, open the VirtualSerialDevice) in a thread that isn't guaranteed to be long-lived.
// Therefore, if we're not in SymbianDeviceManager's thread, rejig things so it's opened in the main thread
if (QThread::currentThread() != thread()) {
// SymbianDeviceManager is owned by the current thread
@@ -378,57 +377,47 @@ TcfTrkDevicePtr SymbianDeviceManager::getTcfPort(const QString &port)
QWaitCondition waiter;
QCoreApplication::postEvent(this, new QConstructTcfPortEvent((QEvent::Type)d->m_constructTcfPortEventType, port, &devicePtr, &waiter));
waiter.wait(&d->m_tcfPortWaitMutex);
- // When the wait returns (due to the wakeAll in SymbianDeviceManager::customEvent), the TcfTrkDevice will be fully set up
+ // When the wait returns (due to the wakeAll in SymbianDeviceManager::customEvent), the CodaDevice will be fully set up
d->m_tcfPortWaitMutex.unlock();
} else {
// We're in the main thread, just set it up directly
constructTcfPort(devicePtr, port);
}
+ // We still carry on in the case we failed to open so the client can access the IODevice's errorString()
}
- if (!devicePtr->device()->isOpen()) {
- bool ok = devicePtr->device().staticCast<SymbianUtils::VirtualSerialDevice>()->open(QIODevice::ReadWrite);
- if (!ok && debug) {
- qDebug("SymbianDeviceManager: Failed to open port %s", qPrintable(port));
- }
- // We still carry on in the case we failed to open so the client can access the IODevice's errorString()
- }
- //Q_ASSERT(QThread::currentThread() == devicePtr->thread());
return devicePtr;
}
-void SymbianDeviceManager::constructTcfPort(TcfTrkDevicePtr& device, const QString& portName)
+void SymbianDeviceManager::constructTcfPort(CodaDevicePtr& device, const QString& portName)
{
QMutexLocker locker(&d->m_tcfPortWaitMutex);
- device = QSharedPointer<tcftrk::TcfTrkDevice>(new tcftrk::TcfTrkDevice);
- const QSharedPointer<SymbianUtils::VirtualSerialDevice> serialDevice(new SymbianUtils::VirtualSerialDevice(portName));
- device->setSerialFrame(true);
- device->setDevice(serialDevice);
+ if (device.isNull()) {
+ device = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice);
+ const QSharedPointer<SymbianUtils::VirtualSerialDevice> serialDevice(new SymbianUtils::VirtualSerialDevice(portName));
+ device->setSerialFrame(true);
+ device->setDevice(serialDevice);
+ }
+ if (!device->device()->isOpen()) {
+ bool ok = device->device().staticCast<SymbianUtils::VirtualSerialDevice>()->open(QIODevice::ReadWrite);
+ if (!ok && debug) {
+ qDebug("SymbianDeviceManager: Failed to open port %s", qPrintable(portName));
+ }
+ }
}
void SymbianDeviceManager::customEvent(QEvent *event)
{
- if (event->type() == d->m_constructTcfPortEventType)
- {
+ if (event->type() == d->m_constructTcfPortEventType) {
QConstructTcfPortEvent* constructEvent = static_cast<QConstructTcfPortEvent*>(event);
constructTcfPort(*constructEvent->m_device, constructEvent->m_portName);
constructEvent->m_waiter->wakeAll(); // Should only ever be one thing waiting on this
}
}
-/*
-TcfTrkDevicePtr SymbianDeviceManager::getTcfPort(const QString &host, quint16 port)
+void SymbianDeviceManager::releaseTcfPort(CodaDevicePtr &aPort)
{
- // No attempt to check the device list. The main purpose in doing that is to cooperatively share the port with other services, and there's no need to do that with TCP/IP as you can just use separate port numbers.
- // Ok it might make it slightly quicker but I'm not going to worry about it just now
-
-}
-*/
-
-void SymbianDeviceManager::releaseTcfPort(TcfTrkDevicePtr &aPort)
-{
- if (aPort) {
+ if (aPort)
aPort.clear();
- }
//TODO close the port after a timeer if last reference?
}
@@ -442,11 +431,10 @@ void SymbianDeviceManager::releaseDevice(const QString &port)
const int idx = findByPortName(port);
if (debug)
qDebug() << "SymbianDeviceManager::releaseDevice" << port << idx << sender();
- if (idx != -1) {
+ if (idx != -1)
d->m_devices[idx].releaseDevice();
- } else {
+ else
qWarning("Attempt to release non-existing device %s.", qPrintable(port));
- }
}
void SymbianDeviceManager::setAdditionalInformation(const QString &port, const QString &ai)
diff --git a/src/shared/symbianutils/symbiandevicemanager.h b/src/shared/symbianutils/symbiandevicemanager.h
index 1ff885c59a..3ebb8aeffb 100644
--- a/src/shared/symbianutils/symbiandevicemanager.h
+++ b/src/shared/symbianutils/symbiandevicemanager.h
@@ -48,8 +48,8 @@ QT_END_NAMESPACE
namespace trk {
class TrkDevice;
}
-namespace tcftrk {
- class TcfTrkDevice;
+namespace Coda {
+ class CodaDevice;
}
namespace SymbianUtils {
@@ -62,7 +62,7 @@ enum DeviceCommunicationType {
BlueToothCommunication = 1
};
-typedef QSharedPointer<tcftrk::TcfTrkDevice> TcfTrkDevicePtr;
+typedef QSharedPointer<Coda::CodaDevice> CodaDevicePtr;
// SymbianDevice: Explicitly shared device data and a TrkDevice
// instance that can be acquired (exclusively) for use.
@@ -146,17 +146,17 @@ public:
// Acquire a TRK device for use. Assuming the port is found, equivalent to devices()[findByPortName(port)].acquireDevice(). See also releaseDevice().
TrkDevicePtr acquireDevice(const QString &port);
- //// The TCF code prefers to set up the TcfTrkDevice object itself, so we let it and just handle opening the underlying QIODevice and keeping track of the TcfTrkDevice
+ //// The TCF code prefers to set up the CodaDevice object itself, so we let it and just handle opening the underlying QIODevice and keeping track of the CodaDevice
//// Returns true if port was opened successfully.
- // Gets the TcfTrkDevice, which may or may not be open depending on what other clients have already acquired it.
- // Therefore once clients have set up any signals and slots they required, they should check TcfTrkDevice::device()->isOpen()
+ // Gets the CodaDevice, which may or may not be open depending on what other clients have already acquired it.
+ // Therefore once clients have set up any signals and slots they required, they should check CodaDevice::device()->isOpen()
// and if false, the open failed and they should check device()->errorString() if required.
// Caller should call releaseTcfPort if they want the port to auto-close itself
- TcfTrkDevicePtr getTcfPort(const QString &port);
+ CodaDevicePtr getTcfPort(const QString &port);
- // Caller is responsible for disconnecting any signals from aPort - do not assume the TcfTrkDevice will be deleted as a result of this call. On return aPort will be clear()ed.
- void releaseTcfPort(TcfTrkDevicePtr &aPort);
+ // Caller is responsible for disconnecting any signals from aPort - do not assume the CodaDevice will be deleted as a result of this call. On return aPort will be clear()ed.
+ void releaseTcfPort(CodaDevicePtr &aPort);
int findByPortName(const QString &p) const;
QString friendlyNameForPort(const QString &port) const;
@@ -178,7 +178,7 @@ private:
SymbianDeviceList serialPorts() const;
SymbianDeviceList blueToothDevices() const;
void customEvent(QEvent *event);
- void constructTcfPort(TcfTrkDevicePtr& device, const QString& portName);
+ void constructTcfPort(CodaDevicePtr& device, const QString& portName);
SymbianDeviceManagerPrivate *d;
};
diff --git a/src/shared/symbianutils/virtualserialdevice_posix.cpp b/src/shared/symbianutils/virtualserialdevice_posix.cpp
index 5fdfc2f5e2..c6598438a3 100644
--- a/src/shared/symbianutils/virtualserialdevice_posix.cpp
+++ b/src/shared/symbianutils/virtualserialdevice_posix.cpp
@@ -127,14 +127,11 @@ bool VirtualSerialDevice::tryWrite(const char *data, qint64 maxSize, qint64& byt
while (maxSize > 0) {
int result = ::write(d->portHandle, data, maxSize);
if (result == -1) {
- if (errno == EAGAIN) {
- // Need to wait
- return true;
- } else {
- setErrorString(QString("Posix error %1 from write to %2").arg(errno).arg(portName));
- bytesWritten = -1;
- return false;
- }
+ if (errno == EAGAIN)
+ return true; // Need to wait
+ setErrorString(QString("Posix error %1 from write to %2").arg(errno).arg(portName));
+ bytesWritten = -1;
+ return false;
} else {
if (result == 0)
qWarning("Zero bytes written to port!");