diff options
author | Laszlo Papp <lpapp@kde.org> | 2013-01-27 05:11:23 +0000 |
---|---|---|
committer | Laszlo Papp <lpapp@kde.org> | 2013-01-27 17:05:23 +0100 |
commit | b0910f0651507a1dc5f4acfbd0a1c225921d080c (patch) | |
tree | 88d004271e9b5bff702d5e2500a66f52891b238b /src/serialport/qserialport_symbian.cpp | |
parent | 6623ce7090138e4169bacdfc0c84cdbfbb78ba77 (diff) |
Make all the file renames and relevant changes
"git log --follow /path/to/the/file/in/question" can be used, for instance, for
the renamed files to get the whole history.
Change-Id: I20da087ca88e2c179a6c3232772fa21575e0aa6a
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Diffstat (limited to 'src/serialport/qserialport_symbian.cpp')
-rw-r--r-- | src/serialport/qserialport_symbian.cpp | 648 |
1 files changed, 648 insertions, 0 deletions
diff --git a/src/serialport/qserialport_symbian.cpp b/src/serialport/qserialport_symbian.cpp new file mode 100644 index 00000000..0cbdc593 --- /dev/null +++ b/src/serialport/qserialport_symbian.cpp @@ -0,0 +1,648 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtSerialPort module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qserialport_symbian_p.h" + +#include <e32base.h> +//#include <e32test.h> +#include <f32file.h> + +QT_BEGIN_NAMESPACE_SERIALPORT + +// Physical device driver. +#ifdef __WINS__ +_LIT(KPddName, "ECDRV"); +#else // defined (__EPOC32__) +_LIT(KPddName, "EUART"); +#endif + +// Logical device driver. +_LIT(KLddName,"ECOMM"); + +// Modules names. +_LIT(KRS232ModuleName, "ECUART"); +_LIT(KBluetoothModuleName, "BTCOMM"); +_LIT(KInfraRedModuleName, "IRCOMM"); +_LIT(KACMModuleName, "ECACM"); + +// Return false on error load. +static bool loadDevices() +{ + TInt r = KErrNone; +#ifdef __WINS__ + RFs fileServer; + r = User::LeaveIfError(fileServer.Connect()); + if (r != KErrNone) + return false; + fileServer.Close (); +#endif + + r = User::LoadPhysicalDevice(KPddName); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); + + r = User::LoadLogicalDevice(KLddName); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); + +#ifndef __WINS__ + r = StartC32(); + if (r != KErrNone && r != KErrAlreadyExists) + return false; //User::Leave(r); +#endif + + return true; +} + +QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) + : QSerialPortPrivateData(q) + , errnum(KErrNone) +{ +} + +bool QSerialPortPrivate::open(QIODevice::OpenMode mode) +{ + // FIXME: Maybe need added check an ReadWrite open mode? + Q_UNUSED(mode) + + if (!loadDevices()) { + portError = QSerialPort::UnknownPortError; + return false; + } + + RCommServ server; + errnum = server.Connect(); + if (errnum != KErrNone) { + portError = decodeSystemError(); + return false; + } + + if (systemLocation.contains("BTCOMM")) + errnum = server.LoadCommModule(KBluetoothModuleName); + else if (systemLocation.contains("IRCOMM")) + errnum = server.LoadCommModule(KInfraRedModuleName); + else if (systemLocation.contains("ACM")) + errnum = server.LoadCommModule(KACMModuleName); + else + errnum = server.LoadCommModule(KRS232ModuleName); + + if (errnum != KErrNone) { + portError = decodeSystemError(); + return false; + } + + // In Symbian OS port opening only in R/W mode? + TPtrC portName(static_cast<const TUint16*>(systemLocation.utf16()), systemLocation.length()); + errnum = descriptor.Open(server, portName, ECommExclusive); + + if (errnum != KErrNone) { + portError = decodeSystemError(); + return false; + } + + // Save current port settings. + errnum = descriptor.Config(restoredSettings); + if (errnum != KErrNone) { + portError = decodeSystemError(); + return false; + } + + detectDefaultSettings(); + return true; +} + +void QSerialPortPrivate::close() +{ + if (restoreSettingsOnClose) + descriptor.SetConfig(restoredSettings); + descriptor.Close(); +} + +QSerialPort::Lines QSerialPortPrivate::lines() const +{ + QSerialPort::Lines ret = 0; + + TUint signalMask = 0; + descriptor.Signals(signalMask); + + if (signalMask & KSignalCTS) + ret |= QSerialPort::CtsLine; + if (signalMask & KSignalDSR) + ret |= QSerialPort::DsrLine; + if (signalMask & KSignalDCD) + ret |= QSerialPort::DcdLine; + if (signalMask & KSignalRNG) + ret |= QSerialPort::RiLine; + if (signalMask & KSignalRTS) + ret |= QSerialPort::RtsLine; + if (signalMask & KSignalDTR) + ret |= QSerialPort::DtrLine; + + //if (signalMask & KSignalBreak) + // ret |= + return ret; +} + +bool QSerialPortPrivate::setDtr(bool set) +{ + TInt r; + if (set) + r = descriptor.SetSignalsToMark(KSignalDTR); + else + r = descriptor.SetSignalsToSpace(KSignalDTR); + + return r == KErrNone; +} + +bool QSerialPortPrivate::setRts(bool set) +{ + TInt r; + if (set) + r = descriptor.SetSignalsToMark(KSignalRTS); + else + r = descriptor.SetSignalsToSpace(KSignalRTS); + + return r == KErrNone; +} + +bool QSerialPortPrivate::flush() +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::clear(QSerialPort::Directions dir) +{ + TUint flags = 0; + if (dir & QSerialPort::Input) + flags |= KCommResetRx; + if (dir & QSerialPort::Output) + flags |= KCommResetTx; + TInt r = descriptor.ResetBuffers(flags); + return r == KErrNone; +} + +bool QSerialPortPrivate::sendBreak(int duration) +{ + TRequestStatus status; + descriptor.Break(status, TTimeIntervalMicroSeconds32(duration * 1000)); + return false; +} + +bool QSerialPortPrivate::setBreak(bool set) +{ + // TODO: Implement me + return false; +} + +qint64 QSerialPortPrivate::systemInputQueueSize () const +{ + return descriptor.QueryReceiveBuffer(); +} + +qint64 QSerialPortPrivate::systemOutputQueueSize () const +{ + // TODO: Implement me + return 0; +} + +qint64 QSerialPortPrivate::bytesAvailable() const +{ + return readBuffer.size(); +} + +qint64 QSerialPortPrivate::readFromBuffer(char *data, qint64 maxSize) +{ + // TODO: Implement me + return -1; +} + +qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +{ + // TODO: Implement me + return -1; +} + +bool QSerialPortPrivate::waitForReadyRead(int msec) +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::waitForBytesWritten(int msec) +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions dir) +{ + if (dir != QSerialPort::AllDirections) { + portError = QSerialPort::UnsupportedPortOperationError; + return false; + } + + baudRate = settingFromBaudRate(baudRate); + if (baudRate) + currentSettings().iRate = static_cast<TBps>(baudRate); + else { + portError = QSerialPort::UnsupportedPortOperationError; + return false; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits) +{ + switch (dataBits) { + case QSerialPort::Data5: + currentSettings().iDataBits = EData5; + break; + case QSerialPort::Data6: + currentSettings().iDataBits = EData6; + break; + case QSerialPort::Data7: + currentSettings().iDataBits = EData7; + break; + case QSerialPort::Data8: + currentSettings().iDataBits = EData8; + break; + default: + currentSettings().iDataBits = EData8; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setParity(QSerialPort::Parity parity) +{ + switch (parity) { + case QSerialPort::NoParity: + currentSettings().iParity = EParityNone; + break; + case QSerialPort::EvenParity: + currentSettings().iParity = EParityEven; + break; + case QSerialPort::OddParity: + currentSettings().iParity = EParityOdd; + break; + case QSerialPort::MarkParity: + currentSettings().iParity = EParityMark; + break; + case QSerialPort::SpaceParity: + currentSettings().iParity = EParitySpace; + break; + default: + currentSettings().iParity = EParityNone; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setStopBits(QSerialPort::StopBits stopBits) +{ + switch (stopBits) { + case QSerialPort::OneStop: + currentSettings().iStopBits = EStop1; + break; + case QSerialPort::TwoStop: + currentSettings().iStopBits = EStop2; + break; + default: + currentSettings().iStopBits = EStop1; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flow) +{ + switch (flow) { + case QSerialPort::NoFlowControl: + currentSettings().iHandshake = KConfigFailDSR; + break; + case QSerialPort::HardwareControl: + currentSettings().iHandshake = KConfigObeyCTS | KConfigFreeRTS; + break; + case QSerialPort::SoftwareControl: + currentSettings().iHandshake = KConfigObeyXoff | KConfigSendXoff; + break; + default: + currentSettings().iHandshake = KConfigFailDSR; + break; + } + + return updateCommConfig(); +} + +bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy) +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::notifyRead() +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::notifyWrite() +{ + // TODO: Implement me + return false; +} + +bool QSerialPortPrivate::updateCommConfig() +{ + if (descriptor.SetConfig(currentSettings) != KErrNone) { + portError = QSerialPort::UnsupportedPortOperationError; + return false; + } + return true; +} + +void QSerialPortPrivate::detectDefaultSettings() +{ + // Detect baud rate. + inputBaudRate = baudRateFromSetting(currentSettings().iRate); + outputBaudRate = inputBaudRate; + + // Detect databits. + switch (currentSettings().iDataBits) { + case EData5: + dataBits = QSerialPort::Data5; + break; + case EData6: + dataBits = QSerialPort::Data6; + break; + case EData7: + dataBits = QSerialPort::Data7; + break; + case EData8: + dataBits = QSerialPort::Data8; + break; + default: + dataBits = QSerialPort::UnknownDataBits; + break; + } + + // Detect parity. + switch (currentSettings().iParity) { + case EParityNone: + parity = QSerialPort::NoParity; + break; + case EParityEven: + parity = QSerialPort::EvenParity; + break; + case EParityOdd: + parity = QSerialPort::OddParity; + break; + case EParityMark: + parity = QSerialPort::MarkParity; + break; + case EParitySpace: + parity = QSerialPort::SpaceParity; + break; + default: + parity = QSerialPort::UnknownParity; + break; + } + + // Detect stopbits. + switch (currentSettings().iStopBits) { + case EStop1: + stopBits = QSerialPort::OneStop; + break; + case EStop2: + stopBits = QSerialPort::TwoStop; + break; + default: + stopBits = QSerialPort::UnknownStopBits; + break; + } + + // Detect flow control. + if ((currentSettings().iHandshake & (KConfigObeyXoff | KConfigSendXoff)) + == (KConfigObeyXoff | KConfigSendXoff)) + flow = QSerialPort::SoftwareControl; + else if ((currentSettings().iHandshake & (KConfigObeyCTS | KConfigFreeRTS)) + == (KConfigObeyCTS | KConfigFreeRTS)) + flow = QSerialPort::HardwareControl; + else if (currentSettings().iHandshake & KConfigFailDSR) + flow = QSerialPort::NoFlowControl; + else + flow = QSerialPort::UnknownFlowControl; +} + +QSerialPort::PortError QSerialPortPrivate::decodeSystemError() const +{ + QSerialPort::PortError error; + switch (errnum) { + case KErrPermissionDenied: + error = QSerialPort::NoSuchDeviceError; + break; + case KErrLocked: + error = QSerialPort::PermissionDeniedError; + break; + case KErrAccessDenied: + error = QSerialPort::PermissionDeniedError; + break; + default: + error = QSerialPort::UnknownPortError; + break; + } + return error; +} + +bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, + bool checkRead, bool checkWrite, + int msecs, bool *timedOut) +{ + + // FIXME: I'm not sure in implementation this method. + // Someone needs to check and correct. + + TRequestStatus timerStatus; + TRequestStatus readStatus; + TRequestStatus writeStatus; + + if (msecs > 0) { + if (!selectTimer.Handle()) { + if (selectTimer.CreateLocal() != KErrNone) + return false; + } + selectTimer.HighRes(timerStatus, msecs * 1000); + } + + if (checkRead) + descriptor.NotifyDataAvailable(readStatus); + + if (checkWrite) + descriptor.NotifyOutputEmpty(writeStatus); + + enum { STATUSES_COUNT = 3 }; + TRequestStatus *statuses[STATUSES_COUNT]; + TInt num = 0; + statuses[num++] = &timerStatus; + statuses[num++] = &readStatus; + statuses[num++] = &writeStatus; + + User::WaitForNRequest(statuses, num); + + bool result = false; + + // By timeout? + if (timerStatus != KRequestPending) { + Q_ASSERT(selectForRead); + *selectForRead = false; + Q_ASSERT(selectForWrite); + *selectForWrite = false; + } else { + selectTimer.Cancel(); + User::WaitForRequest(timerStatus); + + // By read? + if (readStatus != KRequestPending) { + Q_ASSERT(selectForRead); + *selectForRead = true; + } + + // By write? + if (writeStatus != KRequestPending) { + Q_ASSERT(selectForWrite); + *selectForWrite = true; + } + + if (checkRead) + descriptor.NotifyDataAvailableCancel(); + if (checkWrite) + descriptor.NotifyOutputEmptyCancel(); + + result = true; + } + return result; +} + +QString QSerialPortPrivate::portNameToSystemLocation(const QString &port) +{ + // Port name is equval to port systemLocation. + return port; +} + +QString QSerialPortPrivate::portNameFromSystemLocation(const QString &location) +{ + // Port name is equval to port systemLocation. + return location; +} + +struct BaudRatePair +{ + qint32 baudRate; // The numerical value of baud rate. + qint32 setting; // The OS-specific code of baud rate. + bool operator<(const BaudRatePair &other) const { return baudRate < other.baudRate; } + bool operator==(const BaudRatePair &other) const { return setting == other.setting; } +}; + +// This table contains correspondences standard pairs values of +// baud rates that are defined in files +// - d32comm.h for Symbian^3 +// - d32public.h for Symbian SR1 +static const BaudRatePair standardBaudRatesTable[] = +{ + { 50, EBps50 }, + { 75, EBps75 }, + { 110, EBps110}, + { 134, EBps134 }, + { 150, EBps150 }, + { 300, EBps300 }, + { 600, EBps600 }, + { 1200, EBps1200 }, + { 1800, EBps1800 }, + { 2000, EBps2000 }, + { 2400, EBps2400 }, + { 3600, EBps3600 }, + { 4800, EBps4800 }, + { 7200, EBps7200 }, + { 9600, EBps9600 }, + { 19200, EBps19200 }, + { 38400, EBps38400 }, + { 57600, EBps57600 }, + { 115200, EBps115200 }, + { 230400, EBps230400 }, + { 460800, EBps460800 }, + { 576000, EBps576000 }, + { 921600, EBps921600 }, + { 1152000, EBps1152000 }, + //{ 1843200, EBps1843200 }, only for Symbian SR1 + { 4000000, EBps4000000 } +}; + +static const BaudRatePair *standardBaudRatesTable_end = + standardBaudRatesTable + sizeof(standardBaudRatesTable)/sizeof(*standardBaudRatesTable); + +qint32 QSerialPortPrivate::baudRateFromSetting(qint32 setting) +{ + const BaudRatePair rp = { 0, setting }; + const BaudRatePair *ret = qFind(standardaBaudRatesTable, standardBaudRatesTable_end, rp); + return ret != standardBaudRatesTable_end ? ret->baudRate : 0; +} + +qint32 QSerialPortPrivate::settingFromBaudRate(qint32 baudRate) +{ + const BaudRatePair rp = { baudRate, 0 }; + const BaudRatePair *ret = qBinaryFind(standardBaudRatesTable, standardBaudRatesTable_end, rp); + return ret != standardBaudRatesTable_end ? ret->setting : 0; +} + +QList<qint32> QSerialPortPrivate::standardBaudRates() +{ + QList<qint32> ret; + for (const BaudRatePair *it = standardBaudRatesTable; it != standardBaudRatesTable_end; ++it) + ret.append(it->baudRate); + return ret; +} + +QT_END_NAMESPACE_SERIALPORT |