summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-09 15:27:26 +0200
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-09 15:27:26 +0200
commit50956f5476487ee10b1d3a8e339ea3e3222f883d (patch)
treeb21758e348ec4ba4e49de9a0316166c6414e478e
parenteb0dd8763c235b027bea91d5ec7fd82f06cacbab (diff)
parentc0aebf3dfe3c6837db8f91d65ac4b6b7b44e100e (diff)
downloadqtserialport-50956f5476487ee10b1d3a8e339ea3e3222f883d.tar.gz
Merge remote-tracking branch 'origin/5.5' into dev
Change-Id: I913394721091750d64dad3ed0fd08ef8616edcf9
-rw-r--r--examples/serialport/terminal/mainwindow.cpp29
-rw-r--r--examples/serialport/terminal/mainwindow.h5
-rw-r--r--src/serialport/qserialport.cpp87
-rw-r--r--src/serialport/qserialport.h2
-rw-r--r--src/serialport/qserialport_p.h26
-rw-r--r--src/serialport/qserialport_unix.cpp226
-rw-r--r--src/serialport/qserialport_win.cpp198
-rw-r--r--src/serialport/qserialport_wince.cpp118
-rw-r--r--src/serialport/qserialportinfo.cpp2
-rw-r--r--src/serialport/qserialportinfo_mac.cpp13
-rw-r--r--src/serialport/qserialportinfo_unix.cpp11
-rw-r--r--src/serialport/qserialportinfo_win.cpp11
-rw-r--r--src/serialport/qserialportinfo_wince.cpp2
-rw-r--r--tests/auto/qserialport/tst_qserialport.cpp112
-rw-r--r--tests/manual/manual.pro3
-rw-r--r--tests/manual/qserialport/qserialport.pro7
-rw-r--r--tests/manual/qserialport/tst_qserialport.cpp208
-rw-r--r--tests/manual/qserialportinfo/qserialportinfo.pro7
-rw-r--r--tests/manual/qserialportinfo/tst_qserialportinfo.cpp100
-rw-r--r--tests/tests.pro2
20 files changed, 463 insertions, 706 deletions
diff --git a/examples/serialport/terminal/mainwindow.cpp b/examples/serialport/terminal/mainwindow.cpp
index 9a98456..3630b1f 100644
--- a/examples/serialport/terminal/mainwindow.cpp
+++ b/examples/serialport/terminal/mainwindow.cpp
@@ -38,6 +38,7 @@
#include "settingsdialog.h"
#include <QMessageBox>
+#include <QLabel>
#include <QtSerialPort/QSerialPort>
//! [0]
@@ -60,6 +61,9 @@ MainWindow::MainWindow(QWidget *parent) :
ui->actionQuit->setEnabled(true);
ui->actionConfigure->setEnabled(true);
+ status = new QLabel;
+ ui->statusBar->addWidget(status);
+
initActionsConnections();
connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
@@ -90,18 +94,18 @@ void MainWindow::openSerialPort()
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
if (serial->open(QIODevice::ReadWrite)) {
- console->setEnabled(true);
- console->setLocalEchoEnabled(p.localEchoEnabled);
- ui->actionConnect->setEnabled(false);
- ui->actionDisconnect->setEnabled(true);
- ui->actionConfigure->setEnabled(false);
- ui->statusBar->showMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
- .arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
- .arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
+ console->setEnabled(true);
+ console->setLocalEchoEnabled(p.localEchoEnabled);
+ ui->actionConnect->setEnabled(false);
+ ui->actionDisconnect->setEnabled(true);
+ ui->actionConfigure->setEnabled(false);
+ showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
+ .arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
+ .arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
} else {
QMessageBox::critical(this, tr("Error"), serial->errorString());
- ui->statusBar->showMessage(tr("Open error"));
+ showStatusMessage(tr("Open error"));
}
}
//! [4]
@@ -115,7 +119,7 @@ void MainWindow::closeSerialPort()
ui->actionConnect->setEnabled(true);
ui->actionDisconnect->setEnabled(false);
ui->actionConfigure->setEnabled(true);
- ui->statusBar->showMessage(tr("Disconnected"));
+ showStatusMessage(tr("Disconnected"));
}
//! [5]
@@ -162,3 +166,8 @@ void MainWindow::initActionsConnections()
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
connect(ui->actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}
+
+void MainWindow::showStatusMessage(const QString &message)
+{
+ status->setText(message);
+}
diff --git a/examples/serialport/terminal/mainwindow.h b/examples/serialport/terminal/mainwindow.h
index 51524e1..64b9e25 100644
--- a/examples/serialport/terminal/mainwindow.h
+++ b/examples/serialport/terminal/mainwindow.h
@@ -43,6 +43,8 @@
QT_BEGIN_NAMESPACE
+class QLabel;
+
namespace Ui {
class MainWindow;
}
@@ -73,7 +75,10 @@ private:
void initActionsConnections();
private:
+ void showStatusMessage(const QString &message);
+
Ui::MainWindow *ui;
+ QLabel *status;
Console *console;
SettingsDialog *settings;
QSerialPort *serial;
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp
index 9d5aa40..9ed1c5f 100644
--- a/src/serialport/qserialport.cpp
+++ b/src/serialport/qserialport.cpp
@@ -97,6 +97,15 @@ int QSerialPortPrivate::timeoutValue(int msecs, int elapsed)
return qMax(msecs, 0);
}
+void QSerialPortPrivate::setError(const QSerialPortErrorInfo &errorInfo)
+{
+ Q_Q(QSerialPort);
+
+ error = errorInfo.errorCode;
+ q->setErrorString(errorInfo.errorString);
+ emit q->error(error);
+}
+
/*!
\class QSerialPort
@@ -512,14 +521,14 @@ bool QSerialPort::open(OpenMode mode)
Q_D(QSerialPort);
if (isOpen()) {
- setError(QSerialPort::OpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::OpenError, tr("Device is already open")));
return false;
}
// Define while not supported modes.
static const OpenMode unsupportedModes = Append | Truncate | Text | Unbuffered;
if ((mode & unsupportedModes) || mode == NotOpen) {
- setError(QSerialPort::UnsupportedOperationError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError, tr("Unsupported open mode")));
return false;
}
@@ -552,7 +561,7 @@ void QSerialPort::close()
{
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
return;
}
@@ -561,6 +570,7 @@ void QSerialPort::close()
QIODevice::close();
}
+#if QT_DEPRECATED_SINCE(5, 3)
/*!
\property QSerialPort::settingsRestoredOnClose
\brief the flag which specifies to restore the previous settings when closing
@@ -571,7 +581,6 @@ void QSerialPort::close()
The default state of the QSerialPort class is to restore the
settings.
*/
-#if QT_DEPRECATED_SINCE(5,3)
void QSerialPort::setSettingsRestoredOnClose(bool restore)
{
Q_D(QSerialPort);
@@ -588,6 +597,8 @@ bool QSerialPort::settingsRestoredOnClose() const
return d->settingsRestoredOnClose;
}
#endif // QT_DEPRECATED_SINCE(5,3)
+
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
\fn void QSerialPort::settingsRestoredOnCloseChanged(bool restore)
\obsolete
@@ -599,6 +610,7 @@ bool QSerialPort::settingsRestoredOnClose() const
\sa QSerialPort::settingsRestoredOnClose
*/
+#endif // QT_DEPRECATED_SINCE(5, 5)
/*!
\property QSerialPort::baudRate
@@ -862,7 +874,7 @@ bool QSerialPort::setDataTerminalReady(bool set)
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return false;
}
@@ -909,7 +921,7 @@ bool QSerialPort::setRequestToSend(bool set)
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return false;
}
@@ -959,7 +971,7 @@ QSerialPort::PinoutSignals QSerialPort::pinoutSignals()
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return QSerialPort::NoSignal;
}
@@ -989,7 +1001,7 @@ bool QSerialPort::flush()
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return false;
}
@@ -1011,7 +1023,7 @@ bool QSerialPort::clear(Directions directions)
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return false;
}
@@ -1051,6 +1063,7 @@ bool QSerialPort::atEnd() const
return QIODevice::atEnd() && (!isOpen() || (d->buffer.size() == 0));
}
+#if QT_DEPRECATED_SINCE(5, 2)
/*!
\property QSerialPort::dataErrorPolicy
\brief the error policy for how the process receives characters in the case where
@@ -1067,13 +1080,12 @@ bool QSerialPort::atEnd() const
with the kernel and hardware. Hence, the two scenarios cannot be completely
compared to each other.
*/
-#if QT_DEPRECATED_SINCE(5, 2)
bool QSerialPort::setDataErrorPolicy(DataErrorPolicy policy)
{
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return false;
}
@@ -1093,6 +1105,8 @@ QSerialPort::DataErrorPolicy QSerialPort::dataErrorPolicy() const
return d->policy;
}
#endif // QT_DEPRECATED_SINCE(5, 2)
+
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
\fn void QSerialPort::dataErrorPolicyChanged(DataErrorPolicy policy)
\obsolete
@@ -1104,6 +1118,7 @@ QSerialPort::DataErrorPolicy QSerialPort::dataErrorPolicy() const
\sa QSerialPort::dataErrorPolicy
*/
+#endif // QT_DEPRECATED_SINCE(5, 5)
/*!
\property QSerialPort::error
@@ -1124,7 +1139,8 @@ QSerialPort::SerialPortError QSerialPort::error() const
void QSerialPort::clearError()
{
- setError(QSerialPort::NoError);
+ Q_D(QSerialPort);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NoError));
}
/*!
@@ -1211,7 +1227,13 @@ qint64 QSerialPort::bytesAvailable() const
qint64 QSerialPort::bytesToWrite() const
{
Q_D(const QSerialPort);
- return d->bytesToWrite() + QIODevice::bytesToWrite();
+ qint64 bytes = QIODevice::bytesToWrite();
+#ifdef Q_OS_WIN32
+ bytes += d->actualBytesToWrite;
+#else
+ bytes += d->writeBuffer.size();
+#endif
+ return bytes;
}
/*!
@@ -1267,6 +1289,7 @@ bool QSerialPort::waitForBytesWritten(int msecs)
return d->waitForBytesWritten(msecs);
}
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
Sends a continuous stream of zero bits during a specified period
of time \a duration in msec if the terminal is using asynchronous
@@ -1288,13 +1311,14 @@ bool QSerialPort::sendBreak(int duration)
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return false;
}
return d->sendBreak(duration);
}
+#endif // QT_DEPRECATED_SINCE(5, 5)
/*!
\property QSerialPort::breakEnabled
@@ -1317,7 +1341,7 @@ bool QSerialPort::setBreakEnabled(bool set)
Q_D(QSerialPort);
if (!isOpen()) {
- setError(QSerialPort::NotOpenError);
+ d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError, tr("Device is not open")));
qWarning("%s: device not open", Q_FUNC_INFO);
return false;
}
@@ -1341,10 +1365,27 @@ bool QSerialPort::isBreakEnabled() const
/*!
\reimp
*/
+// This function does not really read anything, as we use QIODevicePrivate's
+// buffer. The buffer will be read inside of QIODevice before this
+// method will be called.
qint64 QSerialPort::readData(char *data, qint64 maxSize)
{
Q_D(QSerialPort);
- return d->readData(data, maxSize);
+
+ Q_UNUSED(data);
+ Q_UNUSED(maxSize);
+
+#ifdef Q_OS_WIN32
+ // We need try to start async reading to read a remainder from a driver's queue
+ // in case we have a limited read buffer size. Because the read notification can
+ // be stalled since Windows do not re-triggered an EV_RXCHAR event if a driver's
+ // buffer has a remainder of data ready to read until a new data will be received.
+ if (d->readBufferMaxSize || d->flowControl == QSerialPort::HardwareControl)
+ d->startAsyncRead();
+#endif
+
+ // return 0 indicating there may be more data in the future
+ return qint64(0);
}
/*!
@@ -1364,20 +1405,6 @@ qint64 QSerialPort::writeData(const char *data, qint64 maxSize)
return d->writeData(data, maxSize);
}
-void QSerialPort::setError(QSerialPort::SerialPortError serialPortError, const QString &errorString)
-{
- Q_D(QSerialPort);
-
- d->error = serialPortError;
-
- if (errorString.isNull() && (serialPortError != QSerialPort::NoError))
- setErrorString(qt_error_string(-1));
- else
- setErrorString(errorString);
-
- emit error(serialPortError);
-}
-
#include "moc_qserialport.cpp"
QT_END_NAMESPACE
diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h
index 51ff296..2815ebe 100644
--- a/src/serialport/qserialport.h
+++ b/src/serialport/qserialport.h
@@ -282,8 +282,6 @@ protected:
qint64 writeData(const char *data, qint64 maxSize) Q_DECL_OVERRIDE;
private:
- void setError(QSerialPort::SerialPortError error, const QString &errorString = QString());
-
// ### Qt6: remove me.
QSerialPortPrivate * const d_dummy;
diff --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h
index 7da2204..571b0de 100644
--- a/src/serialport/qserialport_p.h
+++ b/src/serialport/qserialport_p.h
@@ -106,6 +106,19 @@ class QSocketNotifier;
QString serialPortLockFilePath(const QString &portName);
#endif
+class QSerialPortErrorInfo
+{
+public:
+ explicit QSerialPortErrorInfo(QSerialPort::SerialPortError errorCode = QSerialPort::UnknownError,
+ const QString &errorString = QString())
+ : errorCode(errorCode)
+ , errorString(errorString)
+ {
+ }
+ QSerialPort::SerialPortError errorCode;
+ QString errorString;
+};
+
class QSerialPortPrivate : public QIODevicePrivate
{
Q_DECLARE_PUBLIC(QSerialPort)
@@ -133,8 +146,6 @@ public:
bool sendBreak(int duration);
bool setBreakEnabled(bool set);
- qint64 readData(char *data, qint64 maxSize);
-
bool waitForReadyRead(int msec);
bool waitForBytesWritten(int msec);
@@ -146,9 +157,10 @@ public:
bool setFlowControl(QSerialPort::FlowControl flowControl);
bool setDataErrorPolicy(QSerialPort::DataErrorPolicy policy);
- QSerialPort::SerialPortError decodeSystemError(int systemErrorCode = -1) const;
+ QSerialPortErrorInfo getSystemError(int systemErrorCode = -1) const;
+
+ void setError(const QSerialPortErrorInfo &errorInfo);
- qint64 bytesToWrite() const;
qint64 writeData(const char *data, qint64 maxSize);
static QString portNameToSystemLocation(const QString &port);
@@ -240,11 +252,11 @@ public:
bool initialize(QIODevice::OpenMode mode);
bool updateTermios();
- QSerialPort::SerialPortError setBaudRate_helper(qint32 baudRate,
+ QSerialPortErrorInfo setBaudRate_helper(qint32 baudRate,
QSerialPort::Directions directions);
- QSerialPort::SerialPortError setCustomBaudRate(qint32 baudRate,
+ QSerialPortErrorInfo setCustomBaudRate(qint32 baudRate,
QSerialPort::Directions directions);
- QSerialPort::SerialPortError setStandardBaudRate(qint32 baudRate,
+ QSerialPortErrorInfo setStandardBaudRate(qint32 baudRate,
QSerialPort::Directions directions);
bool isReadNotificationEnabled() const;
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index 1f90a18..612d84a 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -77,6 +77,10 @@ QString serialPortLockFilePath(const QString &portName)
<< QStringLiteral("/run/lock")
#ifdef Q_OS_ANDROID
<< QStringLiteral("/data/local/tmp")
+#elif defined(Q_OS_OSX)
+ // This is the workaround to specify a temporary directory
+ // on OSX when running the App Sandbox feature.
+ << QStandardPaths::writableLocation(QStandardPaths::TempLocation);
#endif
;
@@ -98,13 +102,6 @@ QString serialPortLockFilePath(const QString &portName)
}
}
-#ifdef Q_OS_MAC
- // This is the workaround to specify a temporary directory
- // on OSX when running the App Sandbox feature.
- if (lockFilePath.isEmpty())
- lockFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
-#endif
-
if (lockFilePath.isEmpty()) {
qWarning("The following directories are not readable or writable for detaling with lock files\n");
foreach (const QString &lockDirectoryPath, lockDirectoryPaths)
@@ -117,19 +114,21 @@ QString serialPortLockFilePath(const QString &portName)
class ReadNotifier : public QSocketNotifier
{
- Q_OBJECT
public:
ReadNotifier(QSerialPortPrivate *d, QObject *parent)
: QSocketNotifier(d->descriptor, QSocketNotifier::Read, parent)
, dptr(d)
- {}
+ {
+ }
protected:
- bool event(QEvent *e) Q_DECL_OVERRIDE {
- bool ret = QSocketNotifier::event(e);
- if (ret)
+ bool event(QEvent *e) Q_DECL_OVERRIDE
+ {
+ if (e->type() == QEvent::SockAct) {
dptr->readNotification();
- return ret;
+ return true;
+ }
+ return QSocketNotifier::event(e);
}
private:
@@ -138,43 +137,41 @@ private:
class WriteNotifier : public QSocketNotifier
{
- Q_OBJECT
public:
WriteNotifier(QSerialPortPrivate *d, QObject *parent)
: QSocketNotifier(d->descriptor, QSocketNotifier::Write, parent)
, dptr(d)
- {}
+ {
+ }
protected:
- bool event(QEvent *e) Q_DECL_OVERRIDE {
- bool ret = QSocketNotifier::event(e);
- if (ret)
+ bool event(QEvent *e) Q_DECL_OVERRIDE
+ {
+ if (e->type() == QEvent::SockAct) {
dptr->completeAsyncWrite();
- return ret;
+ return true;
+ }
+ return QSocketNotifier::event(e);
}
private:
QSerialPortPrivate *dptr;
};
-#include "qserialport_unix.moc"
-
bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
- Q_Q(QSerialPort);
-
QString lockFilePath = serialPortLockFilePath(QSerialPortInfoPrivate::portNameFromSystemLocation(systemLocation));
bool isLockFileEmpty = lockFilePath.isEmpty();
if (isLockFileEmpty) {
qWarning("Failed to create a lock file for opening the device");
- q->setError(QSerialPort::PermissionError);
+ setError(QSerialPortErrorInfo(QSerialPort::PermissionError, QSerialPort::tr("Permission error while creating lock file")));
return false;
}
QScopedPointer<QLockFile> newLockFileScopedPointer(new QLockFile(lockFilePath));
if (!newLockFileScopedPointer->tryLock()) {
- q->setError(QSerialPort::PermissionError);
+ setError(QSerialPortErrorInfo(QSerialPort::PermissionError, QSerialPort::tr("Permission error while locking the device")));
return false;
}
@@ -195,7 +192,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
descriptor = qt_safe_open(systemLocation.toLocal8Bit().constData(), flags);
if (descriptor == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -211,32 +208,28 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
void QSerialPortPrivate::close()
{
- Q_Q(QSerialPort);
-
if (settingsRestoredOnClose) {
if (::tcsetattr(descriptor, TCSANOW, &restoredTermios) == -1)
- q->setError(decodeSystemError());
+ setError(getSystemError());
}
#ifdef TIOCNXCL
if (::ioctl(descriptor, TIOCNXCL) == -1)
- q->setError(decodeSystemError());
+ setError(getSystemError());
#endif
if (readNotifier) {
- readNotifier->setEnabled(false);
- readNotifier->deleteLater();
+ delete readNotifier;
readNotifier = Q_NULLPTR;
}
if (writeNotifier) {
- writeNotifier->setEnabled(false);
- writeNotifier->deleteLater();
+ delete writeNotifier;
writeNotifier = Q_NULLPTR;
}
if (qt_safe_close(descriptor) == -1)
- q->setError(decodeSystemError());
+ setError(getSystemError());
lockFileScopedPointer.reset(Q_NULLPTR);
@@ -247,12 +240,10 @@ void QSerialPortPrivate::close()
QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
{
- Q_Q(QSerialPort);
-
int arg = 0;
if (::ioctl(descriptor, TIOCMGET, &arg) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return QSerialPort::NoSignal;
}
@@ -306,11 +297,9 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
bool QSerialPortPrivate::setDataTerminalReady(bool set)
{
- Q_Q(QSerialPort);
-
int status = TIOCM_DTR;
if (::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -319,11 +308,9 @@ bool QSerialPortPrivate::setDataTerminalReady(bool set)
bool QSerialPortPrivate::setRequestToSend(bool set)
{
- Q_Q(QSerialPort);
-
int status = TIOCM_RTS;
if (::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -337,11 +324,9 @@ bool QSerialPortPrivate::flush()
bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
{
- Q_Q(QSerialPort);
-
if (::tcflush(descriptor, (directions == QSerialPort::AllDirections)
? TCIOFLUSH : (directions & QSerialPort::Input) ? TCIFLUSH : TCOFLUSH) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -350,10 +335,8 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
bool QSerialPortPrivate::sendBreak(int duration)
{
- Q_Q(QSerialPort);
-
if (::tcsendbreak(descriptor, duration) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -362,21 +345,14 @@ bool QSerialPortPrivate::sendBreak(int duration)
bool QSerialPortPrivate::setBreakEnabled(bool set)
{
- Q_Q(QSerialPort);
-
if (::ioctl(descriptor, set ? TIOCSBRK : TIOCCBRK) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
-{
- return buffer.read(data, maxSize);
-}
-
bool QSerialPortPrivate::waitForReadyRead(int msecs)
{
QElapsedTimer stopWatch;
@@ -433,22 +409,22 @@ bool QSerialPortPrivate::setBaudRate()
&& setBaudRate(outputBaudRate, QSerialPort::Output));
}
-QSerialPort::SerialPortError
+QSerialPortErrorInfo
QSerialPortPrivate::setBaudRate_helper(qint32 baudRate,
QSerialPort::Directions directions)
{
if ((directions & QSerialPort::Input) && ::cfsetispeed(&currentTermios, baudRate) < 0)
- return decodeSystemError();
+ return getSystemError();
if ((directions & QSerialPort::Output) && ::cfsetospeed(&currentTermios, baudRate) < 0)
- return decodeSystemError();
+ return getSystemError();
- return QSerialPort::NoError;
+ return QSerialPortErrorInfo(QSerialPort::NoError);
}
#if defined(Q_OS_LINUX)
-QSerialPort::SerialPortError
+QSerialPortErrorInfo
QSerialPortPrivate::setStandardBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
struct serial_struct currentSerialInfo;
@@ -460,7 +436,7 @@ QSerialPortPrivate::setStandardBaudRate(qint32 baudRate, QSerialPort::Directions
currentSerialInfo.flags &= ~ASYNC_SPD_CUST;
currentSerialInfo.custom_divisor = 0;
if (::ioctl(descriptor, TIOCSSERIAL, &currentSerialInfo) == -1)
- return decodeSystemError();
+ return getSystemError();
}
return setBaudRate_helper(baudRate, directions);
@@ -468,7 +444,7 @@ QSerialPortPrivate::setStandardBaudRate(qint32 baudRate, QSerialPort::Directions
#else
-QSerialPort::SerialPortError
+QSerialPortErrorInfo
QSerialPortPrivate::setStandardBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
return setBaudRate_helper(baudRate, directions);
@@ -478,7 +454,7 @@ QSerialPortPrivate::setStandardBaudRate(qint32 baudRate, QSerialPort::Directions
#if defined(Q_OS_LINUX)
-QSerialPort::SerialPortError
+QSerialPortErrorInfo
QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
Q_UNUSED(directions);
@@ -488,14 +464,14 @@ QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions d
::memset(&currentSerialInfo, 0, sizeof(currentSerialInfo));
if (::ioctl(descriptor, TIOCGSERIAL, &currentSerialInfo) == -1)
- return decodeSystemError();
+ return getSystemError();
currentSerialInfo.flags &= ~ASYNC_SPD_MASK;
currentSerialInfo.flags |= (ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/);
currentSerialInfo.custom_divisor = currentSerialInfo.baud_base / baudRate;
if (currentSerialInfo.custom_divisor == 0)
- return QSerialPort::UnsupportedOperationError;
+ return QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError, QSerialPort::tr("No suitable custom baud rate divisor"));
if (currentSerialInfo.custom_divisor * baudRate != currentSerialInfo.baud_base) {
qWarning("Baud rate of serial port %s is set to %d instead of %d: divisor %f unsupported",
@@ -505,31 +481,31 @@ QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions d
}
if (::ioctl(descriptor, TIOCSSERIAL, &currentSerialInfo) == -1)
- return decodeSystemError();
+ return getSystemError();
return setBaudRate_helper(B38400, directions);
}
#elif defined(Q_OS_MAC)
-QSerialPort::SerialPortError
+QSerialPortErrorInfo
QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
Q_UNUSED(directions);
#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4)
if (::ioctl(descriptor, IOSSIOSPEED, &baudRate) == -1)
- return decodeSystemError();
+ return getSystemError();
- return QSerialPort::NoError;
+ return QSerialPortErrorInfo(QSerialPort::NoError);
#endif
- return QSerialPort::UnsupportedOperationError;
+ return QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError, QSerialPort::tr("Custom baud rate is not supported"));
}
#elif defined(Q_OS_QNX)
-QSerialPort::SerialPortError
+QSerialPortErrorInfo
QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
// On QNX, the values of the 'Bxxxx' constants are set to 'xxxx' (i.e.
@@ -541,36 +517,34 @@ QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions d
#else
-QSerialPort::SerialPortError
+QSerialPortErrorInfo
QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
Q_UNUSED(baudRate);
Q_UNUSED(directions);
- return QSerialPort::UnsupportedOperationError;
+ return QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError);
}
#endif
bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
- Q_Q(QSerialPort);
-
if (baudRate <= 0) {
- q->setError(QSerialPort::UnsupportedOperationError);
+ setError(QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError, QSerialPort::tr("Invalid baud rate value")));
return false;
}
const qint32 unixBaudRate = QSerialPortPrivate::settingFromBaudRate(baudRate);
- const QSerialPort::SerialPortError error = (unixBaudRate > 0)
+ const QSerialPortErrorInfo error = (unixBaudRate > 0)
? setStandardBaudRate(unixBaudRate, directions)
: setCustomBaudRate(baudRate, directions);
- if (error == QSerialPort::NoError)
+ if (error.errorCode == QSerialPort::NoError)
return updateTermios();
- q->setError(error);
+ setError(error);
return false;
}
@@ -727,12 +701,12 @@ bool QSerialPortPrivate::readNotification()
const qint64 readBytes = readFromPort(ptr, bytesToRead);
if (readBytes <= 0) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::ReadError;
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::ResourceError)
+ error.errorCode = QSerialPort::ReadError;
else
setReadNotificationEnabled(false);
- q->setError(error);
+ setError(error);
buffer.chop(bytesToRead);
return false;
}
@@ -759,18 +733,16 @@ bool QSerialPortPrivate::readNotification()
bool QSerialPortPrivate::startAsyncWrite()
{
- Q_Q(QSerialPort);
-
if (writeBuffer.isEmpty() || writeSequenceStarted)
return true;
// Attempt to write it all in one chunk.
qint64 written = writeToPort(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize());
if (written < 0) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::WriteError;
- q->setError(error);
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::ResourceError)
+ error.errorCode = QSerialPort::WriteError;
+ setError(error);
return false;
}
@@ -808,15 +780,13 @@ bool QSerialPortPrivate::completeAsyncWrite()
inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
{
- Q_Q(QSerialPort);
-
#ifdef TIOCEXCL
if (::ioctl(descriptor, TIOCEXCL) == -1)
- q->setError(decodeSystemError());
+ setError(getSystemError());
#endif
if (::tcgetattr(descriptor, &restoredTermios) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -846,11 +816,6 @@ inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
return true;
}
-qint64 QSerialPortPrivate::bytesToWrite() const
-{
- return writeBuffer.size();
-}
-
qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
{
::memcpy(writeBuffer.reserve(maxSize), data, maxSize);
@@ -861,71 +826,72 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
bool QSerialPortPrivate::updateTermios()
{
- Q_Q(QSerialPort);
-
if (::tcsetattr(descriptor, TCSANOW, &currentTermios) == -1) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError(int systemErrorCode) const
+QSerialPortErrorInfo QSerialPortPrivate::getSystemError(int systemErrorCode) const
{
- Q_UNUSED(systemErrorCode);
+ if (systemErrorCode == -1)
+ systemErrorCode = errno;
+
+ QSerialPortErrorInfo error;
+ error.errorString = qt_error_string(systemErrorCode);
- QSerialPort::SerialPortError error;
- switch (errno) {
+ switch (systemErrorCode) {
case ENODEV:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
#ifdef ENOENT
case ENOENT:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
#endif
case EACCES:
- error = QSerialPort::PermissionError;
+ error.errorCode = QSerialPort::PermissionError;
break;
case EBUSY:
- error = QSerialPort::PermissionError;
+ error.errorCode = QSerialPort::PermissionError;
break;
case EAGAIN:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case EIO:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case EBADF:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
#ifdef Q_OS_MAC
case ENXIO:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
#endif
#ifdef EINVAL
case EINVAL:
- error = QSerialPort::UnsupportedOperationError;
+ error.errorCode = QSerialPort::UnsupportedOperationError;
break;
#endif
#ifdef ENOIOCTLCMD
case ENOIOCTLCMD:
- error = QSerialPort::UnsupportedOperationError;
+ error.errorCode = QSerialPort::UnsupportedOperationError;
break;
#endif
#ifdef ENOTTY
case ENOTTY:
- error = QSerialPort::UnsupportedOperationError;
+ error.errorCode = QSerialPort::UnsupportedOperationError;
break;
#endif
#ifdef EPERM
case EPERM:
- error = QSerialPort::PermissionError;
+ error.errorCode = QSerialPort::PermissionError;
break;
#endif
default:
- error = QSerialPort::UnknownError;
+ error.errorCode = QSerialPort::UnknownError;
break;
}
return error;
@@ -969,8 +935,6 @@ bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectFor
bool checkRead, bool checkWrite,
int msecs)
{
- Q_Q(QSerialPort);
-
Q_ASSERT(selectForRead);
Q_ASSERT(selectForWrite);
@@ -990,11 +954,11 @@ bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectFor
const int ret = ::select(descriptor + 1, &fdread, &fdwrite, 0, msecs < 0 ? 0 : &tv);
if (ret < 0) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
if (ret == 0) {
- q->setError(QSerialPort::TimeoutError);
+ setError(QSerialPortErrorInfo(QSerialPort::TimeoutError, QSerialPort::tr("Operation timed out")));
return false;
}
@@ -1081,8 +1045,6 @@ qint64 QSerialPortPrivate::writePerChar(const char *data, qint64 maxSize)
qint64 QSerialPortPrivate::readPerChar(char *data, qint64 maxSize)
{
- Q_Q(QSerialPort);
-
qint64 ret = 0;
quint8 const charMask = (0xFF >> (8 - dataBits));
@@ -1128,13 +1090,15 @@ qint64 QSerialPortPrivate::readPerChar(char *data, qint64 maxSize)
switch (policy) {
case QSerialPort::SkipPolicy:
continue; //ignore received character
- case QSerialPort::StopReceivingPolicy:
+ case QSerialPort::StopReceivingPolicy: {
if (parity != QSerialPort::NoParity)
- q->setError(QSerialPort::ParityError);
+ setError(QSerialPortErrorInfo(QSerialPort::ParityError, QSerialPort::tr("Parity error detected while reading")));
+ else if (*data == '\0')
+ setError(QSerialPortErrorInfo(QSerialPort::BreakConditionError, QSerialPort::tr("Break condition detected while reading")));
else
- q->setError(*data == '\0' ?
- QSerialPort::BreakConditionError : QSerialPort::FramingError);
+ setError(QSerialPortErrorInfo(QSerialPort::FramingError, QSerialPort::tr("Framing error detected while reading")));
return ++ret; //abort receiving
+ }
break;
case QSerialPort::UnknownPolicy:
// Unknown error policy is used! Falling back to PassZeroPolicy
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index e6e6924..a9687a2 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -77,8 +77,6 @@ QT_BEGIN_NAMESPACE
bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
- Q_Q(QSerialPort);
-
DWORD desiredAccess = 0;
originalEventMask = EV_ERR;
@@ -93,7 +91,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
desiredAccess, 0, Q_NULLPTR, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, Q_NULLPTR);
if (handle == INVALID_HANDLE_VALUE) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -106,13 +104,18 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
void QSerialPortPrivate::close()
{
- Q_Q(QSerialPort);
-
if (!::CancelIo(handle))
- q->setError(decodeSystemError());
+ setError(getSystemError());
- if (notifier)
- notifier->deleteLater();
+ if (notifier) {
+ delete notifier;
+ notifier = Q_NULLPTR;
+ }
+
+ if (startAsyncWriteTimer) {
+ delete startAsyncWriteTimer;
+ startAsyncWriteTimer = Q_NULLPTR;
+ }
readStarted = false;
writeStarted = false;
@@ -123,25 +126,23 @@ void QSerialPortPrivate::close()
if (settingsRestoredOnClose) {
if (!::SetCommState(handle, &restoredDcb))
- q->setError(decodeSystemError());
+ setError(getSystemError());
else if (!::SetCommTimeouts(handle, &restoredCommTimeouts))
- q->setError(decodeSystemError());
+ setError(getSystemError());
}
if (!::CloseHandle(handle))
- q->setError(decodeSystemError());
+ setError(getSystemError());
handle = INVALID_HANDLE_VALUE;
}
QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
{
- Q_Q(QSerialPort);
-
DWORD modemStat = 0;
if (!::GetCommModemStatus(handle, &modemStat)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return QSerialPort::NoSignal;
}
@@ -160,7 +161,7 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
if (!::DeviceIoControl(handle, IOCTL_SERIAL_GET_DTRRTS, Q_NULLPTR, 0,
&modemStat, sizeof(modemStat),
&bytesReturned, Q_NULLPTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return ret;
}
@@ -174,10 +175,8 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
bool QSerialPortPrivate::setDataTerminalReady(bool set)
{
- Q_Q(QSerialPort);
-
if (!::EscapeCommFunction(handle, set ? SETDTR : CLRDTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -187,10 +186,8 @@ bool QSerialPortPrivate::setDataTerminalReady(bool set)
bool QSerialPortPrivate::setRequestToSend(bool set)
{
- Q_Q(QSerialPort);
-
if (!::EscapeCommFunction(handle, set ? SETRTS : CLRRTS)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -204,8 +201,6 @@ bool QSerialPortPrivate::flush()
bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
{
- Q_Q(QSerialPort);
-
DWORD flags = 0;
if (directions & QSerialPort::Input)
flags |= PURGE_RXABORT | PURGE_RXCLEAR;
@@ -214,7 +209,7 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
actualBytesToWrite = 0;
}
if (!::PurgeComm(handle, flags)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -242,32 +237,14 @@ bool QSerialPortPrivate::sendBreak(int duration)
bool QSerialPortPrivate::setBreakEnabled(bool set)
{
- Q_Q(QSerialPort);
-
if (set ? !::SetCommBreak(handle) : !::ClearCommBreak(handle)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
-{
- Q_UNUSED(data);
- Q_UNUSED(maxSize);
-
- // We need try to start async reading to read a remainder from a driver's queue
- // in case we have a limited read buffer size. Because the read notification can
- // be stalled since Windows do not re-triggered an EV_RXCHAR event if a driver's
- // buffer has a remainder of data ready to read until a new data will be received.
- if (readBufferMaxSize || flowControl == QSerialPort::HardwareControl)
- startAsyncRead();
-
- // return 0 indicating there may be more data in the future
- return qint64(0);
-}
-
bool QSerialPortPrivate::waitForReadyRead(int msecs)
{
if (!writeStarted && !_q_startAsyncWrite())
@@ -331,10 +308,8 @@ bool QSerialPortPrivate::setBaudRate()
bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
- Q_Q(QSerialPort);
-
if (directions != QSerialPort::AllDirections) {
- q->setError(QSerialPort::UnsupportedOperationError);
+ setError(QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError, QSerialPort::tr("Custom baud rate direction is unsupported")));
return false;
}
currentDcb.BaudRate = baudRate;
@@ -442,18 +417,20 @@ bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred)
if (bytesTransferred > 0) {
char *ptr = buffer.reserve(bytesTransferred);
::memcpy(ptr, readChunkBuffer.constData(), bytesTransferred);
- if (!emulateErrorPolicy())
- emitReadyRead();
}
readStarted = false;
+ bool result = true;
if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
- return startAsyncRead();
+ result = startAsyncRead();
else if (readBufferMaxSize == 0 || readBufferMaxSize > buffer.size())
- return startAsyncCommunication();
- else
- return true;
+ result = startAsyncCommunication();
+
+ if ((bytesTransferred > 0) && !emulateErrorPolicy())
+ emitReadyRead();
+
+ return result;
}
bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred)
@@ -476,15 +453,13 @@ bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred)
bool QSerialPortPrivate::startAsyncCommunication()
{
- Q_Q(QSerialPort);
-
::ZeroMemory(&communicationOverlapped, sizeof(communicationOverlapped));
if (!::WaitCommEvent(handle, &triggeredEventMask, &communicationOverlapped)) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error == QSerialPort::PermissionError)
- error = QSerialPort::ResourceError;
- q->setError(error);
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::NoError) {
+ if (error.errorCode == QSerialPort::PermissionError)
+ error.errorCode = QSerialPort::ResourceError;
+ setError(error);
return false;
}
}
@@ -493,8 +468,6 @@ bool QSerialPortPrivate::startAsyncCommunication()
bool QSerialPortPrivate::startAsyncRead()
{
- Q_Q(QSerialPort);
-
if (readStarted)
return true;
@@ -515,13 +488,13 @@ bool QSerialPortPrivate::startAsyncRead()
return true;
}
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error == QSerialPort::PermissionError)
- error = QSerialPort::ResourceError;
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::ReadError;
- q->setError(error);
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::NoError) {
+ if (error.errorCode == QSerialPort::PermissionError)
+ error.errorCode = QSerialPort::ResourceError;
+ if (error.errorCode != QSerialPort::ResourceError)
+ error.errorCode = QSerialPort::ReadError;
+ setError(error);
return false;
}
@@ -531,8 +504,6 @@ bool QSerialPortPrivate::startAsyncRead()
bool QSerialPortPrivate::_q_startAsyncWrite()
{
- Q_Q(QSerialPort);
-
if (writeBuffer.isEmpty() || writeStarted)
return true;
@@ -541,11 +512,11 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
if (!::WriteFile(handle, writeBuffer.readPointer(),
writeBytes, Q_NULLPTR, &writeCompletionOverlapped)) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::WriteError;
- q->setError(error);
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::NoError) {
+ if (error.errorCode != QSerialPort::ResourceError)
+ error.errorCode = QSerialPort::WriteError;
+ setError(error);
return false;
}
}
@@ -557,11 +528,9 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
void QSerialPortPrivate::_q_notified(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped)
{
- Q_Q(QSerialPort);
-
- const QSerialPort::SerialPortError error = decodeSystemError(errorCode);
- if (error != QSerialPort::NoError) {
- q->setError(error);
+ const QSerialPortErrorInfo error = getSystemError(errorCode);
+ if (error.errorCode != QSerialPort::NoError) {
+ setError(error);
return;
}
@@ -610,11 +579,6 @@ void QSerialPortPrivate::emitReadyRead()
emit q->readyRead();
}
-qint64 QSerialPortPrivate::bytesToWrite() const
-{
- return actualBytesToWrite;
-}
-
qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
{
Q_Q(QSerialPort);
@@ -635,33 +599,29 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
void QSerialPortPrivate::handleLineStatusErrors()
{
- Q_Q(QSerialPort);
-
DWORD errors = 0;
if (!::ClearCommError(handle, &errors, Q_NULLPTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return;
}
if (errors & CE_FRAME) {
- q->setError(QSerialPort::FramingError);
+ setError(QSerialPortErrorInfo(QSerialPort::FramingError, QSerialPort::tr("Framing error detected while reading")));
} else if (errors & CE_RXPARITY) {
- q->setError(QSerialPort::ParityError);
+ setError(QSerialPortErrorInfo(QSerialPort::FramingError, QSerialPort::tr("ParityError error detected while reading")));
parityErrorOccurred = true;
} else if (errors & CE_BREAK) {
- q->setError(QSerialPort::BreakConditionError);
+ setError(QSerialPortErrorInfo(QSerialPort::BreakConditionError, QSerialPort::tr("Break condition detected while reading")));
} else {
- q->setError(QSerialPort::UnknownError);
+ setError(QSerialPortErrorInfo(QSerialPort::UnknownError, QSerialPort::tr("Unknown streaming error")));
}
}
OVERLAPPED *QSerialPortPrivate::waitForNotified(int msecs)
{
- Q_Q(QSerialPort);
-
OVERLAPPED *overlapped = notifier->waitForAnyNotified(msecs);
if (!overlapped) {
- q->setError(decodeSystemError(WAIT_TIMEOUT));
+ setError(getSystemError(WAIT_TIMEOUT));
return 0;
}
return overlapped;
@@ -675,7 +635,7 @@ inline bool QSerialPortPrivate::initialize()
restoredDcb.DCBlength = sizeof(restoredDcb);
if (!::GetCommState(handle, &restoredDcb)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -690,11 +650,13 @@ inline bool QSerialPortPrivate::initialize()
if (currentDcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
currentDcb.fDtrControl = DTR_CONTROL_DISABLE;
+ currentDcb.BaudRate = inputBaudRate;
+
if (!updateDcb())
return false;
if (!::GetCommTimeouts(handle, &restoredCommTimeouts)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -705,7 +667,7 @@ inline bool QSerialPortPrivate::initialize()
return false;
if (!::SetCommMask(handle, originalEventMask)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -723,10 +685,8 @@ inline bool QSerialPortPrivate::initialize()
bool QSerialPortPrivate::updateDcb()
{
- Q_Q(QSerialPort);
-
if (!::SetCommState(handle, &currentDcb)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
@@ -734,60 +694,60 @@ bool QSerialPortPrivate::updateDcb()
bool QSerialPortPrivate::updateCommTimeouts()
{
- Q_Q(QSerialPort);
-
if (!::SetCommTimeouts(handle, &currentCommTimeouts)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError(int systemErrorCode) const
+QSerialPortErrorInfo QSerialPortPrivate::getSystemError(int systemErrorCode) const
{
if (systemErrorCode == -1)
systemErrorCode = ::GetLastError();
- QSerialPort::SerialPortError error;
+ QSerialPortErrorInfo error;
+ error.errorString = qt_error_string(systemErrorCode);
+
switch (systemErrorCode) {
case ERROR_SUCCESS:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_IO_PENDING:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_MORE_DATA:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_FILE_NOT_FOUND:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
case ERROR_INVALID_NAME:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
case ERROR_ACCESS_DENIED:
- error = QSerialPort::PermissionError;
+ error.errorCode = QSerialPort::PermissionError;
break;
case ERROR_INVALID_HANDLE:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_INVALID_PARAMETER:
- error = QSerialPort::UnsupportedOperationError;
+ error.errorCode = QSerialPort::UnsupportedOperationError;
break;
case ERROR_BAD_COMMAND:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_DEVICE_REMOVED:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_OPERATION_ABORTED:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case WAIT_TIMEOUT:
- error = QSerialPort::TimeoutError;
+ error.errorCode = QSerialPort::TimeoutError;
break;
default:
- error = QSerialPort::UnknownError;
+ error.errorCode = QSerialPort::UnknownError;
break;
}
return error;
diff --git a/src/serialport/qserialport_wince.cpp b/src/serialport/qserialport_wince.cpp
index b8affb6..88872ad 100644
--- a/src/serialport/qserialport_wince.cpp
+++ b/src/serialport/qserialport_wince.cpp
@@ -83,21 +83,19 @@ signals:
public:
CommEventNotifier(DWORD mask, QSerialPortPrivate *d, QObject *parent)
- : QThread(parent), dptr(d), running(true) {
+ : QThread(parent), dptr(d) {
connect(this, SIGNAL(eventMask(quint32)), this, SLOT(processNotification(quint32)));
::SetCommMask(dptr->handle, mask);
}
virtual ~CommEventNotifier() {
- running = false;
::SetCommMask(dptr->handle, 0);
- wait();
}
protected:
void run() Q_DECL_OVERRIDE {
DWORD mask = 0;
- while (running) {
+ while (true) {
if (::WaitCommEvent(dptr->handle, &mask, FALSE)) {
// Wait until complete the operation changes the port settings,
// see updateDcb().
@@ -131,7 +129,6 @@ private slots:
private:
QSerialPortPrivate *dptr;
- mutable bool running;
};
class WaitCommEventBreaker : public QThread
@@ -181,8 +178,6 @@ private:
bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
- Q_Q(QSerialPort);
-
DWORD desiredAccess = 0;
DWORD eventMask = EV_ERR;
@@ -199,7 +194,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
desiredAccess, 0, Q_NULLPTR, OPEN_EXISTING, 0, Q_NULLPTR);
if (handle == INVALID_HANDLE_VALUE) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -213,7 +208,9 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
void QSerialPortPrivate::close()
{
if (eventNotifier) {
- eventNotifier->deleteLater();
+ eventNotifier->terminate();
+ eventNotifier->wait();
+ delete eventNotifier;
eventNotifier = Q_NULLPTR;
}
@@ -228,12 +225,10 @@ void QSerialPortPrivate::close()
QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
{
- Q_Q(QSerialPort);
-
DWORD modemStat = 0;
if (!::GetCommModemStatus(handle, &modemStat)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return QSerialPort::NoSignal;
}
@@ -252,7 +247,7 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
if (!::DeviceIoControl(handle, IOCTL_SERIAL_GET_DTRRTS, Q_NULLPTR, 0,
&modemStat, sizeof(modemStat),
&bytesReturned, Q_NULLPTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return ret;
}
@@ -266,10 +261,8 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
bool QSerialPortPrivate::setDataTerminalReady(bool set)
{
- Q_Q(QSerialPort);
-
if (!::EscapeCommFunction(handle, set ? SETDTR : CLRDTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -279,10 +272,8 @@ bool QSerialPortPrivate::setDataTerminalReady(bool set)
bool QSerialPortPrivate::setRequestToSend(bool set)
{
- Q_Q(QSerialPort);
-
if (!::EscapeCommFunction(handle, set ? SETRTS : CLRRTS)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -319,21 +310,14 @@ bool QSerialPortPrivate::sendBreak(int duration)
bool QSerialPortPrivate::setBreakEnabled(bool set)
{
- Q_Q(QSerialPort);
-
if (set ? !::SetCommBreak(handle) : !::ClearCommBreak(handle)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
-{
- return buffer.read(data, maxSize);
-}
-
bool QSerialPortPrivate::waitForReadyRead(int msec)
{
if (!buffer.isEmpty())
@@ -395,10 +379,8 @@ bool QSerialPortPrivate::setBaudRate()
bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
- Q_Q(QSerialPort);
-
if (directions != QSerialPort::AllDirections) {
- q->setError(QSerialPort::UnsupportedOperationError);
+ setError(QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError, QSerialPort::tr("Custom baud rate direction is unsupported")));
return false;
}
currentDcb.BaudRate = baudRate;
@@ -509,11 +491,11 @@ bool QSerialPortPrivate::notifyRead()
if (!sucessResult) {
buffer.chop(bytesToRead);
- q->setError(QSerialPort::ReadError);
+ setError(QSerialPortErrorInfo(QSerialPort::ReadError, QSerialPort::tr("Error reading from device")));
return false;
}
- buffer.chop(readBytes);
+ buffer.chop(bytesToRead - qMax(readBytes, DWORD(0)));
// Process emulate policy.
if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) {
@@ -552,7 +534,7 @@ bool QSerialPortPrivate::notifyWrite()
DWORD bytesWritten = 0;
if (!::WriteFile(handle, ptr, nextSize, &bytesWritten, Q_NULLPTR)) {
- q->setError(QSerialPort::WriteError);
+ setError(QSerialPortErrorInfo(QSerialPort::WriteError, QSerialPort::tr("Error writing to device")));
return false;
}
@@ -564,11 +546,6 @@ bool QSerialPortPrivate::notifyWrite()
return true;
}
-qint64 QSerialPortPrivate::bytesToWrite() const
-{
- return writeBuffer.size();
-}
-
qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
{
::memcpy(writeBuffer.reserve(maxSize), data, maxSize);
@@ -577,30 +554,28 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
return maxSize;
}
-void QSerialPortPrivate::processIoErrors(bool error)
+void QSerialPortPrivate::processIoErrors(bool hasError)
{
- Q_Q(QSerialPort);
-
- if (error) {
- q->setError(QSerialPort::ResourceError);
+ if (hasError) {
+ setError(QSerialPortErrorInfo(QSerialPort::ResourceError, QSerialPort::tr("Device disappeared from the system")));
return;
}
DWORD errors = 0;
if (!::ClearCommError(handle, &errors, Q_NULLPTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return;
}
if (errors & CE_FRAME) {
- q->setError(QSerialPort::FramingError);
+ setError(QSerialPortErrorInfo(QSerialPort::FramingError, QSerialPort::tr("Framing error detected while reading")));
} else if (errors & CE_RXPARITY) {
- q->setError(QSerialPort::ParityError);
+ setError(QSerialPortErrorInfo(QSerialPort::FramingError, QSerialPort::tr("ParityError error detected while reading")));
parityErrorOccurred = true;
} else if (errors & CE_BREAK) {
- q->setError(QSerialPort::BreakConditionError);
+ setError(QSerialPortErrorInfo(QSerialPort::BreakConditionError, QSerialPort::tr("Break condition detected while reading")));
} else {
- q->setError(QSerialPort::UnknownError);
+ setError(QSerialPortErrorInfo(QSerialPort::UnknownError, QSerialPort::tr("Unknown streaming error")));
}
}
@@ -612,7 +587,7 @@ inline bool QSerialPortPrivate::initialize(DWORD eventMask)
restoredDcb.DCBlength = sizeof(restoredDcb);
if (!::GetCommState(handle, &restoredDcb)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -631,7 +606,7 @@ inline bool QSerialPortPrivate::initialize(DWORD eventMask)
return false;
if (!::GetCommTimeouts(handle, &restoredCommTimeouts)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -649,8 +624,6 @@ inline bool QSerialPortPrivate::initialize(DWORD eventMask)
bool QSerialPortPrivate::updateDcb()
{
- Q_Q(QSerialPort);
-
QMutexLocker locker(&settingsChangeMutex);
DWORD eventMask = 0;
@@ -663,7 +636,7 @@ bool QSerialPortPrivate::updateDcb()
// Change parameters
bool ret = ::SetCommState(handle, &currentDcb);
if (!ret)
- q->setError(decodeSystemError());
+ setError(getSystemError());
// Restore the event mask
::SetCommMask(handle, eventMask);
@@ -672,50 +645,51 @@ bool QSerialPortPrivate::updateDcb()
bool QSerialPortPrivate::updateCommTimeouts()
{
- Q_Q(QSerialPort);
-
if (!::SetCommTimeouts(handle, &currentCommTimeouts)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError(int systemErrorCode) const
+QSerialPortErrorInfo QSerialPortPrivate::getSystemError(int systemErrorCode) const
{
- Q_UNUSED(systemErrorCode);
+ if (systemErrorCode == -1)
+ systemErrorCode = ::GetLastError();
- QSerialPort::SerialPortError error;
- switch (::GetLastError()) {
+ QSerialPortErrorInfo error;
+ error.errorString = qt_error_string(systemErrorCode);
+
+ switch (systemErrorCode) {
case ERROR_IO_PENDING:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_MORE_DATA:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_FILE_NOT_FOUND:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
case ERROR_INVALID_NAME:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
case ERROR_ACCESS_DENIED:
- error = QSerialPort::PermissionError;
+ error.errorCode = QSerialPort::PermissionError;
break;
case ERROR_INVALID_HANDLE:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_INVALID_PARAMETER:
- error = QSerialPort::UnsupportedOperationError;
+ error.errorCode = QSerialPort::UnsupportedOperationError;
break;
case ERROR_BAD_COMMAND:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_DEVICE_REMOVED:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
default:
- error = QSerialPort::UnknownError;
+ error.errorCode = QSerialPort::UnknownError;
break;
}
return error;
@@ -725,8 +699,6 @@ bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectFor
bool checkRead, bool checkWrite,
int msecs)
{
- Q_Q(QSerialPort);
-
DWORD eventMask = 0;
// FIXME: Here the situation is not properly handled with zero timeout:
// breaker can work out before you call a method WaitCommEvent()
@@ -736,7 +708,7 @@ bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectFor
breaker.stop();
if (breaker.isWorked()) {
- q->setError(QSerialPort::TimeoutError);
+ setError(QSerialPortErrorInfo(QSerialPort::TimeoutError, QSerialPort::tr("Operation timed out")));
} else {
if (checkRead) {
Q_ASSERT(selectForRead);
diff --git a/src/serialport/qserialportinfo.cpp b/src/serialport/qserialportinfo.cpp
index be3eed1..3e7245e 100644
--- a/src/serialport/qserialportinfo.cpp
+++ b/src/serialport/qserialportinfo.cpp
@@ -266,6 +266,7 @@ bool QSerialPortInfo::hasProductIdentifier() const
\sa isNull()
*/
+#if QT_DEPRECATED_SINCE(5, 2)
/*!
\fn bool QSerialPortInfo::isValid() const
\obsolete
@@ -275,6 +276,7 @@ bool QSerialPortInfo::hasProductIdentifier() const
\sa isNull(), isBusy()
*/
+#endif // QT_DEPRECATED_SINCE(5, 2)
/*!
\fn QList<qint32> QSerialPortInfo::standardBaudRates()
diff --git a/src/serialport/qserialportinfo_mac.cpp b/src/serialport/qserialportinfo_mac.cpp
index 558dcbd..4e73025 100644
--- a/src/serialport/qserialportinfo_mac.cpp
+++ b/src/serialport/qserialportinfo_mac.cpp
@@ -64,7 +64,11 @@ static QCFType<CFTypeRef> searchProperty(io_registry_entry_t ioRegistryEntry,
static QString searchStringProperty(io_registry_entry_t ioRegistryEntry,
const QCFString &propertyKey)
{
- return QCFString::toQString(searchProperty(ioRegistryEntry, propertyKey).as<CFStringRef>());
+ const QCFType<CFTypeRef> result(searchProperty(ioRegistryEntry, propertyKey));
+ const CFStringRef ref = result.as<CFStringRef>();
+ if (ref && (::CFGetTypeID(ref) == ::CFStringGetTypeID()))
+ return QCFString::toQString(ref);
+ return QString();
}
static quint16 searchShortIntProperty(io_registry_entry_t ioRegistryEntry,
@@ -72,9 +76,10 @@ static quint16 searchShortIntProperty(io_registry_entry_t ioRegistryEntry,
bool &ok)
{
const QCFType<CFTypeRef> result(searchProperty(ioRegistryEntry, propertyKey));
+ const CFNumberRef ref = result.as<CFNumberRef>();
quint16 value = 0;
- ok = result.as<CFNumberRef>()
- && (::CFNumberGetValue(result.as<CFNumberRef>(), kCFNumberShortType, &value) > 0);
+ ok = ref && (::CFGetTypeID(ref) == ::CFNumberGetTypeID())
+ && (::CFNumberGetValue(ref, kCFNumberShortType, &value) > 0);
return value;
}
@@ -231,11 +236,13 @@ bool QSerialPortInfo::isBusy() const
return true;
}
+#if QT_DEPRECATED_SINCE(5, 2)
bool QSerialPortInfo::isValid() const
{
QFile f(systemLocation());
return f.exists();
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
QString QSerialPortInfoPrivate::portNameToSystemLocation(const QString &source)
{
diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp
index 0add5b6..0fc5046 100644
--- a/src/serialport/qserialportinfo_unix.cpp
+++ b/src/serialport/qserialportinfo_unix.cpp
@@ -84,6 +84,15 @@ static QStringList filteredDeviceFilePaths()
QStringList deviceFilePaths;
foreach (const QFileInfo &deviceFileInfo, deviceDir.entryInfoList()) {
const QString deviceAbsoluteFilePath = deviceFileInfo.absoluteFilePath();
+
+#ifdef Q_OS_FREEBSD
+ // it is a quick workaround to skip the non-serial devices
+ if (deviceFilePaths.endsWith(QLatin1String(".init"))
+ || deviceFilePaths.endsWith(QLatin1String(".lock"))) {
+ continue;
+ }
+#endif
+
if (!deviceFilePaths.contains(deviceAbsoluteFilePath)) {
deviceFilePaths.append(deviceAbsoluteFilePath);
result.append(deviceAbsoluteFilePath);
@@ -463,11 +472,13 @@ bool QSerialPortInfo::isBusy() const
return true;
}
+#if QT_DEPRECATED_SINCE(5, 2)
bool QSerialPortInfo::isValid() const
{
QFile f(systemLocation());
return f.exists();
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
QString QSerialPortInfoPrivate::portNameToSystemLocation(const QString &source)
{
diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp
index 546d5e1..38190b7 100644
--- a/src/serialport/qserialportinfo_win.cpp
+++ b/src/serialport/qserialportinfo_win.cpp
@@ -65,11 +65,10 @@ static inline const QList<GuidFlagsPair>& guidFlagsPairs()
static QString toStringAndTrimNullCharacter(const QByteArray &buffer)
{
- QString result = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(buffer.constData()),
- buffer.size() / sizeof(wchar_t));
- while (!result.isEmpty() && (result.at(result.size() - 1).unicode() == 0))
- result.chop(1);
- return result;
+ const QString result = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(buffer.constData()),
+ buffer.size() / sizeof(wchar_t));
+ const int index = result.indexOf(QChar(0));
+ return index == -1 ? result : result.mid(0, index);
}
static QStringList portNamesFromHardwareDeviceMap()
@@ -365,6 +364,7 @@ bool QSerialPortInfo::isBusy() const
return false;
}
+#if QT_DEPRECATED_SINCE(5, 2)
bool QSerialPortInfo::isValid() const
{
const HANDLE handle = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation().utf16()),
@@ -378,6 +378,7 @@ bool QSerialPortInfo::isValid() const
}
return true;
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
QString QSerialPortInfoPrivate::portNameToSystemLocation(const QString &source)
{
diff --git a/src/serialport/qserialportinfo_wince.cpp b/src/serialport/qserialportinfo_wince.cpp
index aa590ba..3688bc3 100644
--- a/src/serialport/qserialportinfo_wince.cpp
+++ b/src/serialport/qserialportinfo_wince.cpp
@@ -139,6 +139,7 @@ bool QSerialPortInfo::isBusy() const
return false;
}
+#if QT_DEPRECATED_SINCE(5, 2)
bool QSerialPortInfo::isValid() const
{
const HANDLE handle = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation().utf16()),
@@ -152,6 +153,7 @@ bool QSerialPortInfo::isValid() const
}
return true;
}
+#endif // QT_DEPRECATED_SINCE(5, 2)
QString QSerialPortInfoPrivate::portNameToSystemLocation(const QString &source)
{
diff --git a/tests/auto/qserialport/tst_qserialport.cpp b/tests/auto/qserialport/tst_qserialport.cpp
index 1a714b2..c5c9113 100644
--- a/tests/auto/qserialport/tst_qserialport.cpp
+++ b/tests/auto/qserialport/tst_qserialport.cpp
@@ -35,6 +35,8 @@
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
+#include <QThread>
+
Q_DECLARE_METATYPE(QSerialPort::SerialPortError);
Q_DECLARE_METATYPE(QIODevice::OpenMode);
Q_DECLARE_METATYPE(QIODevice::OpenModeFlag);
@@ -105,6 +107,7 @@ private slots:
#ifdef Q_OS_WIN
void readBufferOverflow();
void readAfterInputClear();
+ void synchronousReadWriteAfterAsynchronousReadWrite();
#endif
void controlBreak();
@@ -324,6 +327,10 @@ void tst_QSerialPort::flush()
QSKIP("flush() does not work on Windows");
#endif
+ // the dummy device on other side also has to be open
+ QSerialPort dummySerialPort(m_receiverPortName);
+ QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));
+
QSerialPort serialPort(m_senderPortName);
connect(&serialPort, SIGNAL(bytesWritten(qint64)), this, SLOT(handleBytesWrittenAndExitLoopSlot(qint64)));
QSignalSpy bytesWrittenSpy(&serialPort, SIGNAL(bytesWritten(qint64)));
@@ -355,6 +362,10 @@ void tst_QSerialPort::doubleFlush()
QSKIP("flush() does not work on Windows");
#endif
+ // the dummy device on other side also has to be open
+ QSerialPort dummySerialPort(m_receiverPortName);
+ QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));
+
QSerialPort serialPort(m_senderPortName);
connect(&serialPort, SIGNAL(bytesWritten(qint64)), this, SLOT(handleBytesWrittenAndExitLoopSlot2(qint64)));
QSignalSpy bytesWrittenSpy(&serialPort, SIGNAL(bytesWritten(qint64)));
@@ -739,6 +750,107 @@ void tst_QSerialPort::readAfterInputClear()
// No more bytes available
QVERIFY(receiverPort.bytesAvailable() == 0);
}
+
+class MasterTransactor : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MasterTransactor(const QString &name)
+ : serialPort(name)
+ {
+ }
+
+public slots:
+ void open()
+ {
+ if (serialPort.open(QSerialPort::ReadWrite)) {
+ createAsynchronousConnection();
+ serialPort.write("A", 1);
+ }
+ }
+
+private slots:
+ void synchronousTransaction()
+ {
+ serialPort.write("B", 1);
+ if (serialPort.waitForBytesWritten(100)) {
+ if (serialPort.waitForReadyRead(100))
+ tst_QSerialPort::exitLoop();
+ }
+ }
+
+ void transaction()
+ {
+ deleteAsyncronousConnection();
+ synchronousTransaction();
+ }
+
+private:
+ void createAsynchronousConnection()
+ {
+ connect(&serialPort, &QSerialPort::readyRead, this, &MasterTransactor::transaction);
+ }
+
+ void deleteAsyncronousConnection()
+ {
+ serialPort.disconnect();
+ }
+
+ QSerialPort serialPort;
+};
+
+class SlaveTransactor : public QObject
+{
+ Q_OBJECT
+public:
+ explicit SlaveTransactor(const QString &name)
+ : serialPort(new QSerialPort(name, this))
+ {
+ connect(serialPort, &QSerialPort::readyRead, this, &SlaveTransactor::transaction);
+ }
+
+public slots:
+ void open()
+ {
+ if (serialPort->open(QSerialPort::ReadWrite))
+ emit ready();
+ }
+
+signals:
+ void ready();
+
+private slots:
+ void transaction()
+ {
+ serialPort->write("Z", 1);
+ }
+
+private:
+ QSerialPort *serialPort;
+};
+
+void tst_QSerialPort::synchronousReadWriteAfterAsynchronousReadWrite()
+{
+ MasterTransactor master(m_senderPortName);
+ SlaveTransactor *slave = new SlaveTransactor(m_receiverPortName);
+
+ QThread thread;
+ slave->moveToThread(&thread);
+ thread.start();
+
+ QObject::connect(&thread, &QThread::finished, slave, &SlaveTransactor::deleteLater);
+ QObject::connect(slave, &SlaveTransactor::ready, &master, &MasterTransactor::open);
+
+ QMetaObject::invokeMethod(slave, "open", Qt::QueuedConnection);
+
+ tst_QSerialPort::enterLoopMsecs(500);
+
+ thread.quit();
+ thread.wait();
+
+ QVERIFY2(!timeout(), "Timed out when testing of transactions.");
+}
+
#endif
class BreakReader : public QObject
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
deleted file mode 100644
index 5be8160..0000000
--- a/tests/manual/manual.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS += qserialportinfo \
- qserialport
diff --git a/tests/manual/qserialport/qserialport.pro b/tests/manual/qserialport/qserialport.pro
deleted file mode 100644
index 3858b6b..0000000
--- a/tests/manual/qserialport/qserialport.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = app
-TARGET = tst_qserialport
-
-QT = core testlib
-QT += serialport
-
-SOURCES += tst_qserialport.cpp
diff --git a/tests/manual/qserialport/tst_qserialport.cpp b/tests/manual/qserialport/tst_qserialport.cpp
deleted file mode 100644
index f6f3252..0000000
--- a/tests/manual/qserialport/tst_qserialport.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtSerialPort module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QDebug>
-
-#include <QtSerialPort/qserialportinfo.h>
-#include <QtSerialPort/qserialport.h>
-
-QT_USE_NAMESPACE
-
-class tst_QSerialPort : public QObject
-{
- Q_OBJECT
-
-private slots:
- void initTestCase();
- void open();
- void baudRate();
- void dataBits();
- void parity();
- void stopBits();
- void flowControl();
-
-private:
- QList<QSerialPortInfo> serialPortInfoList;
-};
-
-void tst_QSerialPort::initTestCase()
-{
- serialPortInfoList = QSerialPortInfo::availablePorts();
-
- if (serialPortInfoList.isEmpty()) {
- QSKIP("Test doesn't work because the serial ports are not detected.");
- }
-}
-
-void tst_QSerialPort::open()
-{
- foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
-
- if (serialPortInfo.isBusy())
- continue;
-
- QSerialPort object1;
-
- // Try open and check access to port by Info
- object1.setPort(serialPortInfo);
- QCOMPARE(object1.portName(), serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
- QCOMPARE(object1.isOpen(), true);
- object1.close();
- QCOMPARE(object1.isOpen(), false);
-
- // Try open and check access to port by Name
- object1.setPortName(serialPortInfo.portName());
- QCOMPARE(object1.portName(), serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
- QCOMPARE(object1.isOpen(), true);
- object1.close();
- QCOMPARE(object1.isOpen(), false);
-
- // Try open and check access to port by Location
- object1.setPortName(serialPortInfo.systemLocation());
- QCOMPARE(object1.portName(), serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
- QCOMPARE(object1.isOpen(), true);
- object1.close();
- QCOMPARE(object1.isOpen(), false);
- }
-}
-
-void tst_QSerialPort::baudRate()
-{
- foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
-
- QSerialPort object1;
- object1.setPortName(serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
-
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud1200), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud1200));
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud2400), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud2400));
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud4800), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud4800));
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud9600), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud9600));
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud19200), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud19200));
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud38400), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud38400));
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud57600), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud57600));
- QCOMPARE(object1.setBaudRate(QSerialPort::Baud115200), true);
- QCOMPARE(object1.baudRate(), static_cast<qint32>(QSerialPort::Baud115200));
-
- object1.close();
- }
-}
-
-void tst_QSerialPort::dataBits()
-{
- foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
-
- QSerialPort object1;
- object1.setPortName(serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
-
- QCOMPARE(object1.setDataBits(QSerialPort::Data8), true);
- QCOMPARE(object1.dataBits(), QSerialPort::Data8);
-
- object1.close();
- }
-}
-
-void tst_QSerialPort::parity()
-{
- foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
-
- QSerialPort object1;
- object1.setPortName(serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
-
- QCOMPARE(object1.setParity(QSerialPort::NoParity), true);
- QCOMPARE(object1.parity(), QSerialPort::NoParity);
- QCOMPARE(object1.setParity(QSerialPort::EvenParity), true);
- QCOMPARE(object1.parity(), QSerialPort::EvenParity);
- QCOMPARE(object1.setParity(QSerialPort::OddParity), true);
- QCOMPARE(object1.parity(), QSerialPort::OddParity);
- QCOMPARE(object1.setParity(QSerialPort::MarkParity), true);
- QCOMPARE(object1.parity(), QSerialPort::MarkParity);
- QCOMPARE(object1.setParity(QSerialPort::SpaceParity), true);
- QCOMPARE(object1.parity(), QSerialPort::SpaceParity);
-
- object1.close();
- }
-}
-
-void tst_QSerialPort::stopBits()
-{
- foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
-
- QSerialPort object1;
- object1.setPortName(serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
-
- QCOMPARE(object1.setStopBits(QSerialPort::OneStop), true);
- QCOMPARE(object1.stopBits(), QSerialPort::OneStop);
- // skip 1.5 stop bits
- QCOMPARE(object1.setStopBits(QSerialPort::TwoStop), true);
- QCOMPARE(object1.stopBits(), QSerialPort::TwoStop);
-
- object1.close();
- }
-}
-
-void tst_QSerialPort::flowControl()
-{
- foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
-
- QSerialPort object1;
- object1.setPortName(serialPortInfo.portName());
- QCOMPARE(object1.open(QIODevice::ReadWrite), true);
-
- QCOMPARE(object1.setFlowControl(QSerialPort::NoFlowControl), true);
- QCOMPARE(object1.flowControl(), QSerialPort::NoFlowControl);
- QCOMPARE(object1.setFlowControl(QSerialPort::HardwareControl), true);
- QCOMPARE(object1.flowControl(), QSerialPort::HardwareControl);
- QCOMPARE(object1.setFlowControl(QSerialPort::SoftwareControl), true);
- QCOMPARE(object1.flowControl(), QSerialPort::SoftwareControl);
-
- object1.close();
- }
-}
-
-QTEST_MAIN(tst_QSerialPort)
-#include "tst_qserialport.moc"
diff --git a/tests/manual/qserialportinfo/qserialportinfo.pro b/tests/manual/qserialportinfo/qserialportinfo.pro
deleted file mode 100644
index 57f6ea6..0000000
--- a/tests/manual/qserialportinfo/qserialportinfo.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = app
-TARGET = tst_qserialportinfo
-
-QT = core testlib
-QT += serialport
-
-SOURCES += tst_qserialportinfo.cpp
diff --git a/tests/manual/qserialportinfo/tst_qserialportinfo.cpp b/tests/manual/qserialportinfo/tst_qserialportinfo.cpp
deleted file mode 100644
index 3bcc0b3..0000000
--- a/tests/manual/qserialportinfo/tst_qserialportinfo.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
-** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtSerialPort module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QDebug>
-
-#include <QtSerialPort/qserialportinfo.h>
-#include <QtSerialPort/qserialport.h>
-
-QT_USE_NAMESPACE
-
-class tst_QSerialPortInfo : public QObject
-{
- Q_OBJECT
-
-private slots:
- void serialPortInfoList();
- void standardBaudRateList();
- void constructors();
- void assignment();
-};
-
-void tst_QSerialPortInfo::serialPortInfoList()
-{
- QList<QSerialPortInfo> list(QSerialPortInfo::availablePorts());
- QCOMPARE(list.isEmpty(), false);
-}
-
-void tst_QSerialPortInfo::standardBaudRateList()
-{
- QList<qint32> list(QSerialPortInfo::standardBaudRates());
- QCOMPARE(list.isEmpty(), false);
-}
-
-void tst_QSerialPortInfo::constructors()
-{
- QSerialPortInfo serialPortInfo;
- QCOMPARE(serialPortInfo.portName().isEmpty(), true);
- QCOMPARE(serialPortInfo.systemLocation().isEmpty(), true);
- QCOMPARE(serialPortInfo.description().isEmpty(), true);
- QCOMPARE(serialPortInfo.manufacturer().isEmpty(), true);
- QCOMPARE(serialPortInfo.serialNumber().isEmpty(), true);
- QCOMPARE(serialPortInfo.vendorIdentifier(), quint16(0));
- QCOMPARE(serialPortInfo.productIdentifier(), quint16(0));
- QCOMPARE(serialPortInfo.hasVendorIdentifier(), false);
- QCOMPARE(serialPortInfo.hasProductIdentifier(), false);
- QCOMPARE(serialPortInfo.isNull(), false);
- QCOMPARE(serialPortInfo.isBusy(), false);
- QCOMPARE(serialPortInfo.isValid(), false);
-}
-
-void tst_QSerialPortInfo::assignment()
-{
- QList<QSerialPortInfo> serialPortInfoList(QSerialPortInfo::availablePorts());
-
- foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
- QSerialPortInfo otherSerialPortInfo = serialPortInfo;
- QCOMPARE(otherSerialPortInfo.portName(), serialPortInfo.portName());
- QCOMPARE(otherSerialPortInfo.systemLocation(), serialPortInfo.systemLocation());
- QCOMPARE(otherSerialPortInfo.description(), serialPortInfo.description());
- QCOMPARE(otherSerialPortInfo.manufacturer(), serialPortInfo.manufacturer());
- QCOMPARE(otherSerialPortInfo.serialNumber(), serialPortInfo.serialNumber());
- QCOMPARE(otherSerialPortInfo.vendorIdentifier(), serialPortInfo.vendorIdentifier());
- QCOMPARE(otherSerialPortInfo.productIdentifier(), serialPortInfo.productIdentifier());
- }
-}
-
-QTEST_MAIN(tst_QSerialPortInfo)
-#include "tst_qserialportinfo.moc"
diff --git a/tests/tests.pro b/tests/tests.pro
index dcc8531..157ef34 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS += auto manual
+SUBDIRS += auto