CODA: Added support for device info button in project settings (for CODA serial connections)

This commit is contained in:
Pawel Polanski
2011-03-02 09:38:17 +01:00
parent 130a55afdc
commit 3d23d26929
11 changed files with 487 additions and 28 deletions

View File

@@ -1043,7 +1043,7 @@ void CodaGdbAdapter::startAdapter()
m_codaSocketIODevice = codaSocket;
} else {
m_codaDevice = SymbianUtils::SymbianDeviceManager::instance()
->getTcfPort(parameters.remoteChannel);
->getCodaDevice(parameters.remoteChannel);
bool ok = m_codaDevice && m_codaDevice->device()->isOpen();
if (!ok) {
@@ -1233,7 +1233,7 @@ void CodaGdbAdapter::cleanup()
// Ensure process is stopped after being suspended.
sendRunControlTerminateCommand();
disconnect(m_codaDevice.data(), 0, this, 0);
SymbianUtils::SymbianDeviceManager::instance()->releaseTcfPort(m_codaDevice);
SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice);
}
}

View File

@@ -117,7 +117,7 @@ bool CodaRunControl::setupLauncher()
if (m_serialPort.length()) {
// We get the port from SymbianDeviceManager
appendMessage(tr("Connecting to '%1'...").arg(m_serialPort), NormalMessageFormat);
m_codaDevice = SymbianUtils::SymbianDeviceManager::instance()->getTcfPort(m_serialPort);
m_codaDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(m_serialPort);
bool ok = m_codaDevice && m_codaDevice->device()->isOpen();
if (!ok) {
@@ -333,7 +333,7 @@ void CodaRunControl::finishRunControl()
m_runningProcessId.clear();
if (m_codaDevice) {
disconnect(m_codaDevice.data(), 0, this, 0);
SymbianUtils::SymbianDeviceManager::instance()->releaseTcfPort(m_codaDevice);
SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice);
}
m_state = StateUninit;
emit finished();
@@ -344,7 +344,7 @@ QMessageBox *CodaRunControl::createCodaWaitingMessageBox(QWidget *parent)
const QString title = tr("Waiting for CODA");
const QString text = tr("Qt Creator is waiting for the CODA application to connect.<br>"
"Please make sure the application is running on "
"your mobile phone and the right IP address and port are "
"your mobile phone and the right IP address and/or port are "
"configured in the project settings.");
QMessageBox *mb = new QMessageBox(QMessageBox::Information, title, text, QMessageBox::Cancel, parent);
return mb;

View File

@@ -41,6 +41,7 @@
#include <symbianutils/launcher.h>
#include <symbianutils/bluetoothlistener.h>
#include <symbianutils/symbiandevicemanager.h>
#include <codadevice.h>
#include "trkruncontrol.h"
@@ -74,6 +75,8 @@ namespace Internal {
const char STARTING_DRIVE_LETTER = 'C';
const char LAST_DRIVE_LETTER = 'Z';
static const quint32 CODA_UID = 0x20021f96;
QString formatDriveText(const S60DeployConfiguration::DeviceDrive &drive)
{
char driveLetter = QChar::toUpper(static_cast<ushort>(drive.first));
@@ -84,6 +87,39 @@ QString formatDriveText(const S60DeployConfiguration::DeviceDrive &drive)
return QString("%1:%2 kB").arg(driveLetter).arg(drive.second);
}
void startTable(QString &text)
{
const char startTableC[] = "<html></head><body><table>";
if (text.contains(startTableC))
return;
text.append(startTableC);
}
void finishTable(QString &text)
{
const char stopTableC[] = "</table></body></html>";
text.replace(stopTableC, QLatin1String(""));
text.append(stopTableC);
}
void addToTable(QTextStream &stream, const QString &key, const QString &value)
{
const char tableRowStartC[] = "<tr><td><b>";
const char tableRowSeparatorC[] = "</b></td><td>";
const char tableRowEndC[] = "</td></tr>";
stream << tableRowStartC << key << tableRowSeparatorC << value << tableRowEndC;
}
void addErrorToTable(QTextStream &stream, const QString &key, const QString &value)
{
const char tableRowStartC[] = "<tr><td><b>";
const char tableRowSeparatorC[] = "</b></td><td>";
const char tableRowEndC[] = "</td></tr>";
const char errorSpanStartC[] = "<span style=\"font-weight:600; color:red; \">";
const char errorSpanEndC[] = "</span>";
stream << tableRowStartC << errorSpanStartC << key << tableRowSeparatorC << value << errorSpanEndC << tableRowEndC;
}
S60DeployConfigurationWidget::S60DeployConfigurationWidget(QWidget *parent)
: ProjectExplorer::DeployConfigurationWidget(parent),
m_detailsWidget(new Utils::DetailsWidget),
@@ -188,6 +224,7 @@ void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc
QHBoxLayout *infoHBoxLayout = new QHBoxLayout;
m_deviceInfoLabel->setWordWrap(true);
m_deviceInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
m_deviceInfoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
infoHBoxLayout->addWidget(m_deviceInfoLabel);
infoHBoxLayout->addWidget(m_deviceInfoButton);
m_deviceInfoButton->setIcon(qApp->style()->standardIcon(QStyle::SP_MessageBoxInformation));
@@ -306,7 +343,8 @@ void S60DeployConfigurationWidget::updateSerialDevices()
const QString newPortName = device(newIndex).portName();
m_deployConfiguration->setSerialPortName(newPortName);
}
if (m_deployConfiguration->communicationChannel() != S60DeployConfiguration::CommunicationTrkSerialConnection)
if (m_deployConfiguration->communicationChannel() != S60DeployConfiguration::CommunicationTrkSerialConnection
&& m_deployConfiguration->communicationChannel() != S60DeployConfiguration::CommunicationCodaSerialConnection)
m_deviceInfoButton->setEnabled(false);
}
@@ -455,10 +493,10 @@ void S60DeployConfigurationWidget::slotWaitingForTrkClosed()
void S60DeployConfigurationWidget::updateDeviceInfo()
{
//TODO: No CODA device info! Implement it when it is available
if (m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationTrkSerialConnection) {
QTC_ASSERT(!m_infoLauncher, return)
setDeviceInfoLabel(tr("Connecting..."));
setDeviceInfoLabel(tr("Connecting..."));
// Do a launcher run with the ping protocol. Prompt to connect and
// go asynchronous afterwards to pop up launch trk box if a timeout occurs.
QString message;
@@ -496,9 +534,185 @@ void S60DeployConfigurationWidget::updateDeviceInfo()
}
// Wait for either timeout or results
m_deviceInfoButton->setEnabled(false);
} else if (m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationCodaSerialConnection) {
setDeviceInfoLabel(tr("Connecting..."));
const SymbianUtils::SymbianDevice commDev = currentDevice();
m_codaInfoDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(commDev.portName());
if (!m_codaInfoDevice->device()->isOpen()) {
setDeviceInfoLabel(m_codaInfoDevice->device()->errorString(), true);
return;
}
//TODO error handling - for now just throw the command at coda
m_codaInfoDevice->sendSymbianOsDataGetQtVersionCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getQtVersionCommandResult));
m_deviceInfoButton->setEnabled(false);
} else
setDeviceInfoLabel(tr("Information about the device is not available when using CODA."), true);
setDeviceInfoLabel(tr("Currently there is no information about device for this connection type."), true);
}
void S60DeployConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result)
{
if (result.type == Coda::CodaCommandResult::FailReply) {
setDeviceInfoLabel(tr("No device information available"), true);
m_deviceInfoButton->setEnabled(true);
return;
} else if (result.type == Coda::CodaCommandResult::CommandErrorReply){
QString message;
startTable(message);
QTextStream str(&message);
addErrorToTable(str, tr("Qt version: "), tr("Not installed on device"));
finishTable(message);
setDeviceInfoLabel(message, false);
} else {
QString resultString;
if (result.values.count()) {
QHash<QString, QVariant> obj = result.values[0].toVariant().toHash();
QString ver = obj.value("qVersion").toString();
startTable(resultString);
QTextStream str(&resultString);
addToTable(str, tr("Qt version: "), ver);
QString systemVersion;
int symVer = obj.value("symbianVersion").toInt();
// Ugh why won't QSysInfo define these on non-symbian builds...
switch (symVer) {
case 10:
systemVersion.append("Symbian OS v9.2");
break;
case 20:
systemVersion.append("Symbian OS v9.3");
break;
case 30:
systemVersion.append("Symbian OS v9.4 / Symbian^1");
break;
case 40:
systemVersion.append("Symbian^2");
break;
case 50:
systemVersion.append("Symbian^3");
break;
case 60:
systemVersion.append("Symbian^4");
break;
default:
systemVersion.append(tr("Unrecognised Symbian version 0x%1").arg(symVer, 0, 16));
break;
}
systemVersion.append(", ");
int s60Ver = obj.value("s60Version").toInt();
switch (s60Ver) {
case 10:
systemVersion.append("S60 3rd Edition Feature Pack 1");
break;
case 20:
systemVersion.append("S60 3rd Edition Feature Pack 2");
break;
case 30:
systemVersion.append("S60 5th Edition");
break;
case 40:
systemVersion.append("S60 5th Edition Feature Pack 1");
break;
case 50:
systemVersion.append("S60 5th Edition Feature Pack 2");
break;
default:
systemVersion.append(tr("Unrecognised S60 version 0x%1").arg(symVer, 0, 16));
break;
}
addToTable(str, tr("OS version: "), systemVersion);
finishTable(resultString);
}
setDeviceInfoLabel(resultString);
}
m_codaInfoDevice->sendSymbianOsDataGetRomInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getRomInfoResult));
}
void S60DeployConfigurationWidget::getRomInfoResult(const Coda::CodaCommandResult &result)
{
if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) {
QString resultString = m_deviceInfoLabel->text();
startTable(resultString);
QTextStream str(&resultString);
QVariantHash obj = result.values[0].toVariant().toHash();
QString romVersion = obj.value("romVersion", tr("unknown")).toString();
romVersion.replace('\n', " "); // The ROM string is split across multiple lines, for some reason.
addToTable(str, tr("ROM version: "), romVersion);
QString pr = obj.value("prInfo").toString();
if (pr.length())
addToTable(str, tr("Release:"), pr);
finishTable(resultString);
setDeviceInfoLabel(resultString);
}
QList<quint32> packagesOfInterest;
packagesOfInterest.append(CODA_UID);
m_codaInfoDevice->sendSymbianInstallGetPackageInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getInstalledPackagesResult), packagesOfInterest);
}
void S60DeployConfigurationWidget::getInstalledPackagesResult(const Coda::CodaCommandResult &result)
{
if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) {
QString resultString = m_deviceInfoLabel->text();
startTable(resultString);
QTextStream str(&resultString);
QVariantList resultsList = result.values[0].toVariant().toList();
foreach (const QVariant& var, resultsList) {
QVariantHash obj = var.toHash();
if (obj.value("uid").toString().toUInt(0, 16) == CODA_UID) {
if (!obj.value("error").isNull()) {
// How can coda not be installed? Presumably some UID wrongness...
addErrorToTable(str, tr("CODA version: "), tr("Error reading CODA version"));
} else {
QVariantList version = obj.value("version").toList();
addToTable(str, tr("CODA version: "),
QString("%1.%2.%3").arg(version[0].toInt())
.arg(version[1].toInt())
.arg(version[2].toInt()));
}
}
}
finishTable(resultString);
setDeviceInfoLabel(resultString);
}
QStringList keys;
keys << QLatin1String("EDisplayXPixels");
keys << QLatin1String("EDisplayYPixels");
//keys << "EMemoryRAMFree";
m_codaInfoDevice->sendSymbianOsDataGetHalInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getHalResult), keys);
}
void S60DeployConfigurationWidget::getHalResult(const Coda::CodaCommandResult &result)
{
if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) {
QString resultString = m_deviceInfoLabel->text();
QVariantList resultsList = result.values[0].toVariant().toList();
int x = 0;
int y = 0;
foreach (const QVariant& var, resultsList) {
QVariantHash obj = var.toHash();
if (obj.value("name").toString() == "EDisplayXPixels")
x = obj.value("value").toInt();
else if (obj.value("name").toString() == "EDisplayYPixels")
y = obj.value("value").toInt();
}
if (x && y) {
startTable(resultString);
QTextStream str(&resultString);
addToTable(str, tr("Screen size: "), QString("%1x%2").arg(x).arg(y));
finishTable(resultString);
setDeviceInfoLabel(resultString);
}
}
// Done with collecting info
m_deviceInfoButton->setEnabled(true);
SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice);
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -61,6 +61,11 @@ namespace SymbianUtils {
class SymbianDevice;
}
namespace Coda {
class CodaDevice;
struct CodaCommandResult;
}
namespace Qt4ProjectManager {
namespace Internal {
@@ -102,6 +107,11 @@ private:
QWidget * createCommunicationChannel();
void getQtVersionCommandResult(const Coda::CodaCommandResult &result);
void getRomInfoResult(const Coda::CodaCommandResult &result);
void getInstalledPackagesResult(const Coda::CodaCommandResult &result);
void getHalResult(const Coda::CodaCommandResult &result);
S60DeployConfiguration *m_deployConfiguration;
Utils::DetailsWidget *m_detailsWidget;
QComboBox *m_serialPortsCombo;
@@ -117,6 +127,7 @@ private:
Utils::IpAddressLineEdit *m_ipAddress;
QRadioButton *m_trkRadioButton;
QRadioButton *m_codaRadioButton;
QSharedPointer<Coda::CodaDevice> m_codaInfoDevice;
};
} // namespace Internal

View File

@@ -317,7 +317,7 @@ void S60DeployStep::stop()
} else {
if (m_codaDevice) {
disconnect(m_codaDevice.data(), 0, this, 0);
SymbianUtils::SymbianDeviceManager::instance()->releaseTcfPort(m_codaDevice);
SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice);
}
}
emit finished(false);
@@ -384,7 +384,7 @@ void S60DeployStep::startDeployment()
}
} else if (m_channel == S60DeployConfiguration::CommunicationCodaSerialConnection) {
appendMessage(tr("Deploying application to '%1'...").arg(m_serialPortFriendlyName), false);
m_codaDevice = SymbianUtils::SymbianDeviceManager::instance()->getTcfPort(m_serialPortName);
m_codaDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(m_serialPortName);
bool ok = m_codaDevice && m_codaDevice->device()->isOpen();
if (!ok) {
QString deviceError = tr("No such port");
@@ -442,7 +442,7 @@ void S60DeployStep::run(QFutureInterface<bool> &fi)
if (m_codaDevice) {
disconnect(m_codaDevice.data(), 0, this, 0);
SymbianUtils::SymbianDeviceManager::instance()->releaseTcfPort(m_codaDevice);
SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice);
}
delete m_eventLoop;

View File

@@ -936,8 +936,6 @@ void CodaDevice::sendProcessStartCommand(const CodaCallback &callBack,
const QString sysBin = QLatin1String("c:/sys/bin");
const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1);
// Fixup: Does argv[0] convention exist on Symbian?
arguments.push_front(binaryFileName);
if (workingDirectory.isEmpty())
workingDirectory = sysBin;
@@ -1316,8 +1314,7 @@ void CodaDevice::sendRegistersSetCommand(const CodaCallback &callBack,
value, cookie);
}
//static const char outputListenerIDC[] = "org.eclipse.cdt.debug.edc.ui.ProgramOutputConsoleLogger";
static const char outputListenerIDC[] = "ProgramOutputConsoleLogger"; //TODO: this one might be the correct one
static const char outputListenerIDC[] = "ProgramOutputConsoleLogger";
void CodaDevice::sendLoggingAddListenerCommand(const CodaCallback &callBack,
const QVariant &cookie)
@@ -1346,6 +1343,34 @@ void CodaDevice::sendSymbianOsDataFindProcessesCommand(const CodaCallback &callB
sendCodaMessage(MessageWithReply, SymbianOSData, "findRunningProcesses", data, callBack, cookie);
}
void CodaDevice::sendSymbianOsDataGetQtVersionCommand(const CodaCallback &callBack,
const QVariant &cookie)
{
sendCodaMessage(MessageWithReply, SymbianOSData, "getQtVersion", QByteArray(), callBack, cookie);
}
void CodaDevice::sendSymbianOsDataGetRomInfoCommand(const CodaCallback &callBack,
const QVariant &cookie)
{
sendCodaMessage(MessageWithReply, SymbianOSData, "getRomInfo", QByteArray(), callBack, cookie);
}
void CodaDevice::sendSymbianOsDataGetHalInfoCommand(const CodaCallback &callBack,
const QStringList &keys,
const QVariant &cookie)
{
QByteArray data;
JsonInputStream str(data);
str << '[';
for (int i = 0; i < keys.count(); ++i) {
if (i)
str << ',';
str << keys[i];
}
str << ']';
sendCodaMessage(MessageWithReply, SymbianOSData, "getHalInfo", data, callBack, cookie);
}
void Coda::CodaDevice::sendFileSystemOpenCommand(const Coda::CodaCallback &callBack,
const QByteArray &name,
unsigned flags,
@@ -1409,4 +1434,24 @@ void Coda::CodaDevice::sendSymbianInstallUIInstallCommand(const Coda::CodaCallba
str << file;
sendCodaMessage(MessageWithReply, SymbianInstallService, "installWithUI", data, callBack, cookie);
}
void Coda::CodaDevice::sendSymbianInstallGetPackageInfoCommand(const Coda::CodaCallback &callBack,
const QList<quint32> &packages,
const QVariant &cookie)
{
QByteArray data;
JsonInputStream str(data);
str << '[';
for (int i = 0; i < packages.count(); ++i) {
if (i)
str << ',';
QString pkgString;
pkgString.setNum(packages[i], 16);
str << pkgString;
}
str << ']';
sendCodaMessage(MessageWithReply, SymbianInstallService, "getPackageInfo", data, callBack, cookie);
}
} // namespace Coda

View File

@@ -131,11 +131,6 @@ http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services
* Commands can be sent along with callbacks that are passed a
* CodaCommandResult and an opaque QVariant cookie. In addition, events are emitted.
*
* Note: As of 11.8.2010, TCF Trk 4.0.5 does not currently support 'Registers::getm'
* (get multiple registers). So, CodaDevice emulates it by sending a sequence of
* single commands. As soon as 'Registers::getm' is natively supported, all code
* related to 'FakeRegisterGetm' should be removed. The workaround requires that
* the register name is known.
* CODA notes:
* - Commands are accepted only after receiving the Locator Hello event
* - Serial communication initiation sequence:
@@ -351,6 +346,10 @@ public:
const QByteArray &file,
const QVariant &cookie = QVariant());
void sendSymbianInstallGetPackageInfoCommand(const Coda::CodaCallback &callBack,
const QList<quint32> &packages,
const QVariant &cookie = QVariant());
void sendLoggingAddListenerCommand(const CodaCallback &callBack,
const QVariant &cookie = QVariant());
@@ -363,6 +362,16 @@ public:
const QByteArray &uid,
const QVariant &cookie = QVariant());
void sendSymbianOsDataGetQtVersionCommand(const CodaCallback &callBack,
const QVariant &cookie = QVariant());
void sendSymbianOsDataGetRomInfoCommand(const CodaCallback &callBack,
const QVariant &cookie = QVariant());
void sendSymbianOsDataGetHalInfoCommand(const CodaCallback &callBack,
const QStringList &keys = QStringList(),
const QVariant &cookie = QVariant());
// Settings
void sendSettingsEnableLogCommand();

View File

@@ -415,6 +415,45 @@ QByteArray JsonValue::toString(bool multiline, int indent) const
return result;
}
QVariant JsonValue::toVariant() const
{
switch (m_type) {
case String:
return QString(m_data);
case Number: {
bool ok;
qint64 val = QString(m_data).toLongLong(&ok);
if (ok)
return val;
return QVariant();
}
case Object: {
QHash<QString, QVariant> hash;
for (int i = 0; i < m_children.size(); ++i) {
QString name(m_children[i].name());
QVariant val = m_children[i].toVariant();
hash.insert(name, val);
}
return hash;
}
case Array: {
QList<QVariant> list;
for (int i = 0; i < m_children.size(); ++i) {
list.append(m_children[i].toVariant());
}
return list;
}
case Boolean:
return data() == QByteArray("true");
case Invalid:
case NullObject:
default:
return QVariant();
}
}
void JsonValue::fromString(const QByteArray &ba)
{
const char *from = ba.constBegin();

View File

@@ -87,6 +87,8 @@ public:
void fromString(const QByteArray &str);
void setStreamOutput(const QByteArray &name, const QByteArray &content);
QVariant toVariant() const;
private:
static QByteArray parseCString(const char *&from, const char *to);
static QByteArray parseNumber(const char *&from, const char *to);

View File

@@ -355,7 +355,7 @@ SymbianDeviceManager::TrkDevicePtr
return rc;
}
CodaDevicePtr SymbianDeviceManager::getTcfPort(const QString &port)
CodaDevicePtr SymbianDeviceManager::getCodaDevice(const QString &port)
{
ensureInitialized();
const int idx = findByPortName(port);
@@ -419,7 +419,7 @@ void SymbianDeviceManager::customEvent(QEvent *event)
}
}
void SymbianDeviceManager::releaseTcfPort(CodaDevicePtr &port)
void SymbianDeviceManager::releaseCodaDevice(CodaDevicePtr &port)
{
if (port) {
// Check if this was the last reference to the port, if so close it after a short delay
@@ -613,4 +613,106 @@ SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm)
return d;
}
} // namespace SymbianUtilsInternal
OstChannel *SymbianDeviceManager::getOstChannel(const QString &port, uchar channelId)
{
CodaDevicePtr coda = getCodaDevice(port);
if (coda.isNull() || !coda->device()->isOpen())
return 0;
return new OstChannel(coda, channelId);
}
struct OstChannelPrivate
{
CodaDevicePtr m_codaPtr;
QByteArray m_dataBuffer;
uchar m_channelId;
bool m_hasReceivedData;
};
OstChannel::OstChannel(const CodaDevicePtr &codaPtr, uchar channelId)
: d(new OstChannelPrivate)
{
d->m_codaPtr = codaPtr;
d->m_channelId = channelId;
d->m_hasReceivedData = false;
connect(codaPtr.data(), SIGNAL(unknownEvent(uchar, QByteArray)), this, SLOT(ostDataReceived(uchar,QByteArray)));
connect(codaPtr->device().data(), SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose()));
QIODevice::open(ReadWrite|Unbuffered);
}
void OstChannel::close()
{
QIODevice::close();
if (d && d->m_codaPtr.data()) {
disconnect(d->m_codaPtr.data(), 0, this, 0);
SymbianDeviceManager::instance()->releaseCodaDevice(d->m_codaPtr);
}
}
OstChannel::~OstChannel()
{
close();
delete d;
}
void OstChannel::flush()
{
//TODO d->m_codaPtr->device()-
}
qint64 OstChannel::bytesAvailable() const
{
return d->m_dataBuffer.size();
}
bool OstChannel::isSequential() const
{
return true;
}
qint64 OstChannel::readData(char *data, qint64 maxSize)
{
qint64 amount = qMin(maxSize, (qint64)d->m_dataBuffer.size());
qMemCopy(data, d->m_dataBuffer.constData(), amount);
d->m_dataBuffer.remove(0, amount);
return amount;
}
qint64 OstChannel::writeData(const char *data, qint64 maxSize)
{
static const qint64 KMaxOstPayload = 1022;
// If necessary, split the packet up
while (maxSize) {
QByteArray dataBuf = QByteArray::fromRawData(data, qMin(KMaxOstPayload, maxSize));
d->m_codaPtr->writeCustomData(d->m_channelId, dataBuf);
data += dataBuf.length();
maxSize -= dataBuf.length();
}
return maxSize;
}
void OstChannel::ostDataReceived(uchar channelId, const QByteArray &aData)
{
if (channelId == d->m_channelId) {
d->m_hasReceivedData = true;
d->m_dataBuffer.append(aData);
emit readyRead();
}
}
Coda::CodaDevice& OstChannel::codaDevice() const
{
return *d->m_codaPtr;
}
bool OstChannel::hasReceivedData() const
{
return isOpen() && d->m_hasReceivedData;
}
void OstChannel::deviceAboutToClose()
{
close();
}
} // namespace SymbianUtils

View File

@@ -36,7 +36,7 @@
#include "symbianutils_global.h"
#include <QtCore/QObject>
#include <QtCore/QIODevice>
#include <QtCore/QExplicitlySharedDataPointer>
#include <QtCore/QSharedPointer>
@@ -56,6 +56,7 @@ namespace SymbianUtils {
struct SymbianDeviceManagerPrivate;
class SymbianDeviceData;
class OstChannel;
enum DeviceCommunicationType {
SerialPortCommunication = 0,
@@ -152,11 +153,15 @@ public:
// 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
CodaDevicePtr getTcfPort(const QString &port);
// Caller should call releaseCodaDevice if they want the port to auto-close itself
CodaDevicePtr getCodaDevice(const QString &port);
// Note this function makes no guarantee that someone else isn't already listening on this channel id, or that there is anything on the other end
// Returns NULL if the port couldn't be opened
OstChannel *getOstChannel(const QString &port, uchar channelId);
// 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);
void releaseCodaDevice(CodaDevicePtr &aPort);
int findByPortName(const QString &p) const;
QString friendlyNameForPort(const QString &port) const;
@@ -188,6 +193,38 @@ private:
SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &);
struct OstChannelPrivate;
class SYMBIANUTILS_EXPORT OstChannel : public QIODevice
{
Q_OBJECT
public:
void close();
~OstChannel();
void flush();
qint64 bytesAvailable() const;
bool isSequential() const;
bool hasReceivedData() const;
Coda::CodaDevice &codaDevice() const;
private slots:
void ostDataReceived(uchar channelId, const QByteArray &aData);
void deviceAboutToClose();
private:
OstChannel(const CodaDevicePtr &codaPtr, uchar channelId);
Q_DISABLE_COPY(OstChannel)
qint64 readData(char *data, qint64 maxSize);
qint64 writeData(const char *data, qint64 maxSize);
private:
OstChannelPrivate *d;
friend class SymbianDeviceManager;
};
} // namespace SymbianUtils
#endif // SYMBIANDEVICEMANAGER_H