From c1355ae41ee46437e9d6583dc4ea452a82b6b53b Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Fri, 13 May 2016 14:53:09 +0300 Subject: Add changelog for Qt 5.6.1 Change-Id: I6337d0334e21f208fdfba3e0947680d5ff17780c Reviewed-by: Leena Miettinen Reviewed-by: Oswald Buddenhagen Reviewed-by: Kai Koehne --- dist/changes-5.6.1 | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 dist/changes-5.6.1 diff --git a/dist/changes-5.6.1 b/dist/changes-5.6.1 new file mode 100644 index 0000000..d7bfb27 --- /dev/null +++ b/dist/changes-5.6.1 @@ -0,0 +1,31 @@ +Qt 5.6.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + + - QSerialPortInfo: + * Added enumeration of dial-in serial ports on FreeBSD. + * [QTBUG-50895] Added enumeration of dial-in serial ports on OS X. + * Added receiving of USB dongle's serial number on Windows. + + - QSerialPort: + * Prohibited changing of RTS in HardwareFlowControl mode. + * [QTBUG-48677] Fixed reading of data remainder with the CDC USB device on Windows. -- cgit v1.2.1 From 9d758fb370026cb531d98ba42e98a8d6fabe6c0a Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Wed, 15 Jun 2016 08:38:43 +0800 Subject: Expand license scope from "Qt GUI Toolkit" to "Qt Toolkit" See http://comments.gmane.org/gmane.comp.lib.qt.devel/25771 Change-Id: Id73b94c13dd718cf849e3e1901f32b40b2f62bdf Reviewed-by: Lars Knoll --- LICENSE.GPLv2 | 2 +- LICENSE.GPLv3 | 2 +- LICENSE.LGPLv21 | 2 +- LICENSE.LGPLv3 | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LICENSE.GPLv2 b/LICENSE.GPLv2 index 6dbb032..a424477 100644 --- a/LICENSE.GPLv2 +++ b/LICENSE.GPLv2 @@ -3,7 +3,7 @@ The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ - You may use, distribute and copy the Qt GUI Toolkit under the terms of + You may use, distribute and copy the Qt Toolkit under the terms of GNU General Public License version 2, which is displayed below. ------------------------------------------------------------------------- diff --git a/LICENSE.GPLv3 b/LICENSE.GPLv3 index 4e49b12..71c4ad4 100644 --- a/LICENSE.GPLv3 +++ b/LICENSE.GPLv3 @@ -3,7 +3,7 @@ The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ - You may use, distribute and copy the Qt GUI Toolkit under the terms of + You may use, distribute and copy the Qt Toolkit under the terms of GNU Lesser General Public License version 3. That license references the General Public License version 3, that is displayed below. Other portions of the Qt Toolkit may be licensed directly under this license. diff --git a/LICENSE.LGPLv21 b/LICENSE.LGPLv21 index 6e18461..dfcab5e 100644 --- a/LICENSE.LGPLv21 +++ b/LICENSE.LGPLv21 @@ -3,7 +3,7 @@ The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ - You may use, distribute and copy the Qt GUI Toolkit under the terms of + You may use, distribute and copy the Qt Toolkit under the terms of GNU Lesser General Public License version 2.1, which is displayed below. ------------------------------------------------------------------------- diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 index 4d67bac..6bf924c 100644 --- a/LICENSE.LGPLv3 +++ b/LICENSE.LGPLv3 @@ -3,7 +3,7 @@ The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ - You may use, distribute and copy the Qt GUI Toolkit under the terms of + You may use, distribute and copy the Qt Toolkit under the terms of GNU Lesser General Public License version 3, which is displayed below. This license makes reference to the version 3 of the GNU General Public License, which you can find in the LICENSE.GPLv3 file. -- cgit v1.2.1 From a713565d119c39bd31ec25926ded881d1f0b78b7 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Thu, 30 Jun 2016 09:32:39 +0300 Subject: Add tests for RTS and DTR signals Change-Id: I148339d731b77975ce56fa79a3ead485bbf02a87 Reviewed-by: Sergey Belyashov Reviewed-by: Denis Shienkov --- tests/auto/qserialport/tst_qserialport.cpp | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/tests/auto/qserialport/tst_qserialport.cpp b/tests/auto/qserialport/tst_qserialport.cpp index 24c0134..33a48fe 100644 --- a/tests/auto/qserialport/tst_qserialport.cpp +++ b/tests/auto/qserialport/tst_qserialport.cpp @@ -96,6 +96,9 @@ private slots: void flowControl_data(); void flowControl(); + void rts(); + void dtr(); + void flush(); void doubleFlush(); @@ -149,6 +152,7 @@ const QByteArray tst_QSerialPort::newlineArray("\n\r"); tst_QSerialPort::tst_QSerialPort() { + qRegisterMetaType("QSerialPort::SerialPortError"); } void tst_QSerialPort::initTestCase() @@ -468,6 +472,83 @@ void tst_QSerialPort::flowControl() } } +void tst_QSerialPort::rts() +{ + QSerialPort serialPort(m_senderPortName); + + QSignalSpy errorSpy(&serialPort, static_cast(&QSerialPort::error)); + QVERIFY(errorSpy.isValid()); + QSignalSpy rtsSpy(&serialPort, &QSerialPort::requestToSendChanged); + QVERIFY(rtsSpy.isValid()); + + QVERIFY(serialPort.open(QIODevice::ReadWrite)); + + // no flow control + QVERIFY(serialPort.setFlowControl(QSerialPort::NoFlowControl)); + const bool toggle1 = !serialPort.isRequestToSend(); + QVERIFY(serialPort.setRequestToSend(toggle1)); + QCOMPARE(serialPort.isRequestToSend(), toggle1); + + // software flow control + QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl)); + const bool toggle2 = !serialPort.isRequestToSend(); + QVERIFY(serialPort.setRequestToSend(toggle2)); + QCOMPARE(serialPort.isRequestToSend(), toggle2); + + // hardware flow control + QVERIFY(serialPort.setFlowControl(QSerialPort::HardwareControl)); + const bool toggle3 = !serialPort.isRequestToSend(); + QVERIFY(!serialPort.setRequestToSend(toggle3)); // not allowed + QCOMPARE(serialPort.isRequestToSend(), !toggle3); // same as before + QCOMPARE(serialPort.error(), QSerialPort::UnsupportedOperationError); + + QCOMPARE(errorSpy.count(), 2); + QCOMPARE(qvariant_cast(errorSpy.at(0).at(0)), QSerialPort::NoError); + QCOMPARE(qvariant_cast(errorSpy.at(1).at(0)), QSerialPort::UnsupportedOperationError); + + QCOMPARE(rtsSpy.count(), 2); + QCOMPARE(qvariant_cast(rtsSpy.at(0).at(0)), toggle1); + QCOMPARE(qvariant_cast(rtsSpy.at(1).at(0)), toggle2); +} + +void tst_QSerialPort::dtr() +{ + QSerialPort serialPort(m_senderPortName); + + QSignalSpy errorSpy(&serialPort, static_cast(&QSerialPort::error)); + QVERIFY(errorSpy.isValid()); + QSignalSpy dtrSpy(&serialPort, &QSerialPort::dataTerminalReadyChanged); + QVERIFY(dtrSpy.isValid()); + + QVERIFY(serialPort.open(QIODevice::ReadWrite)); + + // no flow control + QVERIFY(serialPort.setFlowControl(QSerialPort::NoFlowControl)); + const bool toggle1 = !serialPort.isDataTerminalReady(); + QVERIFY(serialPort.setDataTerminalReady(toggle1)); + QCOMPARE(serialPort.isDataTerminalReady(), toggle1); + + // software flow control + QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl)); + const bool toggle2 = !serialPort.isDataTerminalReady(); + QVERIFY(serialPort.setDataTerminalReady(toggle2)); + QCOMPARE(serialPort.isDataTerminalReady(), toggle2); + + // hardware flow control + QVERIFY(serialPort.setFlowControl(QSerialPort::HardwareControl)); + const bool toggle3 = !serialPort.isDataTerminalReady(); + QVERIFY(serialPort.setDataTerminalReady(toggle3)); + QCOMPARE(serialPort.isDataTerminalReady(), toggle3); + + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(qvariant_cast(errorSpy.at(0).at(0)), QSerialPort::NoError); + + QCOMPARE(dtrSpy.count(), 3); + QCOMPARE(qvariant_cast(dtrSpy.at(0).at(0)), toggle1); + QCOMPARE(qvariant_cast(dtrSpy.at(1).at(0)), toggle2); + QCOMPARE(qvariant_cast(dtrSpy.at(2).at(0)), toggle3); +} + void tst_QSerialPort::handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten) { QCOMPARE(bytesWritten, qint64(alphabetArray.size() + newlineArray.size())); -- cgit v1.2.1 From 5ddbb6b87266d0f8d7dffc03c86c2e80b3735d2c Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Thu, 30 Jun 2016 19:27:25 +0300 Subject: Minimize number of system calls at opening Currently, the method QSP::open() several times calls the system functions to get/set of DCB/termios structures for each parameter. It is not rational and should be minimized as possible, in ideally to once executed. Change-Id: If1f308176a82f3c8896fc648bf656f089e099f3f Reviewed-by: Sergey Belyashov Reviewed-by: Denis Shienkov --- src/serialport/qserialport.cpp | 9 -- src/serialport/qserialport_unix.cpp | 221 +++++++++++++++++++++--------------- src/serialport/qserialport_win.cpp | 172 +++++++++++++++++----------- 3 files changed, 233 insertions(+), 169 deletions(-) diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp index 45f56c8..d4e9a4f 100644 --- a/src/serialport/qserialport.cpp +++ b/src/serialport/qserialport.cpp @@ -568,15 +568,6 @@ bool QSerialPort::open(OpenMode mode) if (!d->open(mode)) return false; - if (!d->setBaudRate() - || !d->setDataBits(d->dataBits) - || !d->setParity(d->parity) - || !d->setStopBits(d->stopBits) - || !d->setFlowControl(d->flowControl)) { - d->close(); - return false; - } - QIODevice::open(mode); return true; } diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index acc53c8..acd76b5 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -193,6 +193,120 @@ private: QSerialPortPrivate *dptr; }; +static inline void qt_set_common_props(termios *tio, QIODevice::OpenMode m) +{ +#ifdef Q_OS_SOLARIS + tio->c_iflag &= ~(IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + tio->c_oflag &= ~OPOST; + tio->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + tio->c_cflag &= ~(CSIZE|PARENB); + tio->c_cflag |= CS8; +#else + ::cfmakeraw(tio); +#endif + + tio->c_cflag |= CLOCAL; + tio->c_cc[VTIME] = 0; + tio->c_cc[VMIN] = 0; + + if (m & QIODevice::ReadOnly) + tio->c_cflag |= CREAD; +} + +static inline void qt_set_databits(termios *tio, QSerialPort::DataBits databits) +{ + tio->c_cflag &= ~CSIZE; + switch (databits) { + case QSerialPort::Data5: + tio->c_cflag |= CS5; + break; + case QSerialPort::Data6: + tio->c_cflag |= CS6; + break; + case QSerialPort::Data7: + tio->c_cflag |= CS7; + break; + case QSerialPort::Data8: + tio->c_cflag |= CS8; + break; + default: + tio->c_cflag |= CS8; + break; + } +} + +static inline void qt_set_parity(termios *tio, QSerialPort::Parity parity) +{ + tio->c_iflag &= ~(PARMRK | INPCK); + tio->c_iflag |= IGNPAR; + + switch (parity) { + +#ifdef CMSPAR + // Here Installation parity only for GNU/Linux where the macro CMSPAR. + case QSerialPort::SpaceParity: + tio->c_cflag &= ~PARODD; + tio->c_cflag |= PARENB | CMSPAR; + break; + case QSerialPort::MarkParity: + tio->c_cflag |= PARENB | CMSPAR | PARODD; + break; +#endif + case QSerialPort::NoParity: + tio->c_cflag &= ~PARENB; + break; + case QSerialPort::EvenParity: + tio->c_cflag &= ~PARODD; + tio->c_cflag |= PARENB; + break; + case QSerialPort::OddParity: + tio->c_cflag |= PARENB | PARODD; + break; + default: + tio->c_cflag |= PARENB; + tio->c_iflag |= PARMRK | INPCK; + tio->c_iflag &= ~IGNPAR; + break; + } +} + +static inline void qt_set_stopbits(termios *tio, QSerialPort::StopBits stopbits) +{ + switch (stopbits) { + case QSerialPort::OneStop: + tio->c_cflag &= ~CSTOPB; + break; + case QSerialPort::TwoStop: + tio->c_cflag |= CSTOPB; + break; + default: + tio->c_cflag &= ~CSTOPB; + break; + } +} + +static inline void qt_set_flowcontrol(termios *tio, QSerialPort::FlowControl flowcontrol) +{ + switch (flowcontrol) { + case QSerialPort::NoFlowControl: + tio->c_cflag &= ~CRTSCTS; + tio->c_iflag &= ~(IXON | IXOFF | IXANY); + break; + case QSerialPort::HardwareControl: + tio->c_cflag |= CRTSCTS; + tio->c_iflag &= ~(IXON | IXOFF | IXANY); + break; + case QSerialPort::SoftwareControl: + tio->c_cflag &= ~CRTSCTS; + tio->c_iflag |= IXON | IXOFF | IXANY; + break; + default: + tio->c_cflag &= ~CRTSCTS; + tio->c_iflag &= ~(IXON | IXOFF | IXANY); + break; + } +} + bool QSerialPortPrivate::open(QIODevice::OpenMode mode) { QString lockFilePath = serialPortLockFilePath(QSerialPortInfoPrivate::portNameFromSystemLocation(systemLocation)); @@ -605,24 +719,8 @@ bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits) if (!getTermios(&tio)) return false; - tio.c_cflag &= ~CSIZE; - switch (dataBits) { - case QSerialPort::Data5: - tio.c_cflag |= CS5; - break; - case QSerialPort::Data6: - tio.c_cflag |= CS6; - break; - case QSerialPort::Data7: - tio.c_cflag |= CS7; - break; - case QSerialPort::Data8: - tio.c_cflag |= CS8; - break; - default: - tio.c_cflag |= CS8; - break; - } + qt_set_databits(&tio, dataBits); + return setTermios(&tio); } @@ -632,37 +730,7 @@ bool QSerialPortPrivate::setParity(QSerialPort::Parity parity) if (!getTermios(&tio)) return false; - tio.c_iflag &= ~(PARMRK | INPCK); - tio.c_iflag |= IGNPAR; - - switch (parity) { - -#ifdef CMSPAR - // Here Installation parity only for GNU/Linux where the macro CMSPAR. - case QSerialPort::SpaceParity: - tio.c_cflag &= ~PARODD; - tio.c_cflag |= PARENB | CMSPAR; - break; - case QSerialPort::MarkParity: - tio.c_cflag |= PARENB | CMSPAR | PARODD; - break; -#endif - case QSerialPort::NoParity: - tio.c_cflag &= ~PARENB; - break; - case QSerialPort::EvenParity: - tio.c_cflag &= ~PARODD; - tio.c_cflag |= PARENB; - break; - case QSerialPort::OddParity: - tio.c_cflag |= PARENB | PARODD; - break; - default: - tio.c_cflag |= PARENB; - tio.c_iflag |= PARMRK | INPCK; - tio.c_iflag &= ~IGNPAR; - break; - } + qt_set_parity(&tio, parity); return setTermios(&tio); } @@ -673,17 +741,8 @@ bool QSerialPortPrivate::setStopBits(QSerialPort::StopBits stopBits) if (!getTermios(&tio)) return false; - switch (stopBits) { - case QSerialPort::OneStop: - tio.c_cflag &= ~CSTOPB; - break; - case QSerialPort::TwoStop: - tio.c_cflag |= CSTOPB; - break; - default: - tio.c_cflag &= ~CSTOPB; - break; - } + qt_set_stopbits(&tio, stopBits); + return setTermios(&tio); } @@ -693,24 +752,8 @@ bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flowControl) if (!getTermios(&tio)) return false; - switch (flowControl) { - case QSerialPort::NoFlowControl: - tio.c_cflag &= ~CRTSCTS; - tio.c_iflag &= ~(IXON | IXOFF | IXANY); - break; - case QSerialPort::HardwareControl: - tio.c_cflag |= CRTSCTS; - tio.c_iflag &= ~(IXON | IXOFF | IXANY); - break; - case QSerialPort::SoftwareControl: - tio.c_cflag &= ~CRTSCTS; - tio.c_iflag |= IXON | IXOFF | IXANY; - break; - default: - tio.c_cflag &= ~CRTSCTS; - tio.c_iflag &= ~(IXON | IXOFF | IXANY); - break; - } + qt_set_flowcontrol(&tio, flowControl); + return setTermios(&tio); } @@ -825,25 +868,19 @@ inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode) return false; restoredTermios = tio; -#ifdef Q_OS_SOLARIS - tio.c_iflag &= ~(IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); - tio.c_oflag &= ~OPOST; - tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - tio.c_cflag &= ~(CSIZE|PARENB); - tio.c_cflag |= CS8; -#else - ::cfmakeraw(&tio); -#endif - tio.c_cflag |= CLOCAL; - tio.c_cc[VTIME] = 0; - tio.c_cc[VMIN] = 0; - if (mode & QIODevice::ReadOnly) - tio.c_cflag |= CREAD; + qt_set_common_props(&tio, mode); + qt_set_databits(&tio, dataBits); + qt_set_parity(&tio, parity); + qt_set_stopbits(&tio, stopBits); + qt_set_flowcontrol(&tio, flowControl); if (!setTermios(&tio)) return false; + if (!setBaudRate()) + return false; + if (mode & QIODevice::ReadOnly) setReadNotificationEnabled(true); diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index 7cbb81d..f4f8317 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -81,6 +81,94 @@ QT_BEGIN_NAMESPACE +static inline void qt_set_common_props(DCB *dcb) +{ + dcb->fBinary = TRUE; + dcb->fAbortOnError = FALSE; + dcb->fNull = FALSE; + dcb->fErrorChar = FALSE; + + if (dcb->fDtrControl == DTR_CONTROL_HANDSHAKE) + dcb->fDtrControl = DTR_CONTROL_DISABLE; +} + +static inline void qt_set_baudrate(DCB *dcb, qint32 baudrate) +{ + dcb->BaudRate = baudrate; +} + +static inline void qt_set_databits(DCB *dcb, QSerialPort::DataBits databits) +{ + dcb->ByteSize = databits; +} + +static inline void qt_set_parity(DCB *dcb, QSerialPort::Parity parity) +{ + dcb->fParity = TRUE; + switch (parity) { + case QSerialPort::NoParity: + dcb->Parity = NOPARITY; + dcb->fParity = FALSE; + break; + case QSerialPort::OddParity: + dcb->Parity = ODDPARITY; + break; + case QSerialPort::EvenParity: + dcb->Parity = EVENPARITY; + break; + case QSerialPort::MarkParity: + dcb->Parity = MARKPARITY; + break; + case QSerialPort::SpaceParity: + dcb->Parity = SPACEPARITY; + break; + default: + dcb->Parity = NOPARITY; + dcb->fParity = FALSE; + break; + } +} + +static inline void qt_set_stopbits(DCB *dcb, QSerialPort::StopBits stopbits) +{ + switch (stopbits) { + case QSerialPort::OneStop: + dcb->StopBits = ONESTOPBIT; + break; + case QSerialPort::OneAndHalfStop: + dcb->StopBits = ONE5STOPBITS; + break; + case QSerialPort::TwoStop: + dcb->StopBits = TWOSTOPBITS; + break; + default: + dcb->StopBits = ONESTOPBIT; + break; + } +} + +static inline void qt_set_flowcontrol(DCB *dcb, QSerialPort::FlowControl flowcontrol) +{ + dcb->fInX = FALSE; + dcb->fOutX = FALSE; + dcb->fOutxCtsFlow = FALSE; + dcb->fRtsControl = RTS_CONTROL_DISABLE; + switch (flowcontrol) { + case QSerialPort::NoFlowControl: + break; + case QSerialPort::SoftwareControl: + dcb->fInX = TRUE; + dcb->fOutX = TRUE; + break; + case QSerialPort::HardwareControl: + dcb->fOutxCtsFlow = TRUE; + dcb->fRtsControl = RTS_CONTROL_HANDSHAKE; + break; + default: + break; + } +} + bool QSerialPortPrivate::open(QIODevice::OpenMode mode) { DWORD desiredAccess = 0; @@ -319,7 +407,8 @@ bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions di if (!getDcb(&dcb)) return false; - dcb.BaudRate = baudRate; + qt_set_baudrate(&dcb, baudRate); + return setDcb(&dcb); } @@ -329,7 +418,8 @@ bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits) if (!getDcb(&dcb)) return false; - dcb.ByteSize = dataBits; + qt_set_databits(&dcb, dataBits); + return setDcb(&dcb); } @@ -339,29 +429,8 @@ bool QSerialPortPrivate::setParity(QSerialPort::Parity parity) if (!getDcb(&dcb)) return false; - dcb.fParity = TRUE; - switch (parity) { - case QSerialPort::NoParity: - dcb.Parity = NOPARITY; - dcb.fParity = FALSE; - break; - case QSerialPort::OddParity: - dcb.Parity = ODDPARITY; - break; - case QSerialPort::EvenParity: - dcb.Parity = EVENPARITY; - break; - case QSerialPort::MarkParity: - dcb.Parity = MARKPARITY; - break; - case QSerialPort::SpaceParity: - dcb.Parity = SPACEPARITY; - break; - default: - dcb.Parity = NOPARITY; - dcb.fParity = FALSE; - break; - } + qt_set_parity(&dcb, parity); + return setDcb(&dcb); } @@ -371,20 +440,8 @@ bool QSerialPortPrivate::setStopBits(QSerialPort::StopBits stopBits) if (!getDcb(&dcb)) return false; - switch (stopBits) { - case QSerialPort::OneStop: - dcb.StopBits = ONESTOPBIT; - break; - case QSerialPort::OneAndHalfStop: - dcb.StopBits = ONE5STOPBITS; - break; - case QSerialPort::TwoStop: - dcb.StopBits = TWOSTOPBITS; - break; - default: - dcb.StopBits = ONESTOPBIT; - break; - } + qt_set_stopbits(&dcb, stopBits); + return setDcb(&dcb); } @@ -394,24 +451,8 @@ bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flowControl) if (!getDcb(&dcb)) return false; - dcb.fInX = FALSE; - dcb.fOutX = FALSE; - dcb.fOutxCtsFlow = FALSE; - dcb.fRtsControl = RTS_CONTROL_DISABLE; - switch (flowControl) { - case QSerialPort::NoFlowControl: - break; - case QSerialPort::SoftwareControl: - dcb.fInX = TRUE; - dcb.fOutX = TRUE; - break; - case QSerialPort::HardwareControl: - dcb.fOutxCtsFlow = TRUE; - dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; - break; - default: - break; - } + qt_set_flowcontrol(&dcb, flowControl); + return setDcb(&dcb); } @@ -623,17 +664,12 @@ inline bool QSerialPortPrivate::initialize() restoredDcb = dcb; - dcb.fBinary = TRUE; - dcb.fInX = FALSE; - dcb.fOutX = FALSE; - dcb.fAbortOnError = FALSE; - dcb.fNull = FALSE; - dcb.fErrorChar = FALSE; - - if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE) - dcb.fDtrControl = DTR_CONTROL_DISABLE; - - dcb.BaudRate = inputBaudRate; + qt_set_common_props(&dcb); + qt_set_baudrate(&dcb, inputBaudRate); + qt_set_databits(&dcb, dataBits); + qt_set_parity(&dcb, parity); + qt_set_stopbits(&dcb, stopBits); + qt_set_flowcontrol(&dcb, flowControl); if (!setDcb(&dcb)) return false; -- cgit v1.2.1 From 09f6a0f1cacd8d04d5ec8413eed712308395f962 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Thu, 7 Jul 2016 18:22:17 +0300 Subject: Use append() instead of memcpy() where possible ... to add the data to the internal QIODevice's buffer, that simplified the code and is more reliable. Change-Id: I61e6c7be3259cd754e4bbe6a3142dcdd6d33f7b6 Reviewed-by: Anton Kudryavtsev Reviewed-by: Sergey Belyashov Reviewed-by: Denis Shienkov --- src/serialport/qserialport_unix.cpp | 2 +- src/serialport/qserialport_win.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index acd76b5..8e06ada 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -889,7 +889,7 @@ inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode) qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize) { - ::memcpy(writeBuffer.reserve(maxSize), data, maxSize); + writeBuffer.append(data, maxSize); if (!writeBuffer.isEmpty() && !isWriteNotificationEnabled()) setWriteNotificationEnabled(true); return maxSize; diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index f4f8317..ae32fcf 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -472,10 +472,8 @@ bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred) readStarted = false; return false; } - if (bytesTransferred > 0) { - char *ptr = buffer.reserve(bytesTransferred); - ::memcpy(ptr, readChunkBuffer.constData(), bytesTransferred); - } + if (bytesTransferred > 0) + buffer.append(readChunkBuffer.constData(), bytesTransferred); readStarted = false; @@ -620,7 +618,7 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize) { Q_Q(QSerialPort); - ::memcpy(writeBuffer.reserve(maxSize), data, maxSize); + writeBuffer.append(data, maxSize); actualBytesToWrite += maxSize; if (!writeBuffer.isEmpty() && !writeStarted) { -- cgit v1.2.1 From 86b6a8f27a098d764a5c2f7dc37edb349bd28c3c Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 11 Jul 2016 10:49:06 +0300 Subject: QSerialPortInfo: use delegate ctor to de-duplicate code Change-Id: I698b9afc7b15bdfca7176ea3ec823da1ba91957c Reviewed-by: Sergey Belyashov Reviewed-by: Denis Shienkov --- src/serialport/qserialportinfo.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/serialport/qserialportinfo.cpp b/src/serialport/qserialportinfo.cpp index 2b69966..d978665 100644 --- a/src/serialport/qserialportinfo.cpp +++ b/src/serialport/qserialportinfo.cpp @@ -87,14 +87,8 @@ QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo &other) Constructs a QSerialPortInfo object from serial \a port. */ QSerialPortInfo::QSerialPortInfo(const QSerialPort &port) + : QSerialPortInfo(port.portName()) { - const auto infos = QSerialPortInfo::availablePorts(); - for (const QSerialPortInfo &info : infos) { - if (port.portName() == info.portName()) { - *this = info; - break; - } - } } /*! -- cgit v1.2.1 From fbb174127c8f6a5c74db1d4d85e43e8467a16f1c Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Thu, 7 Jul 2016 21:37:49 +0300 Subject: Start the write timer only when it is inactive Change-Id: Ie6dd49bec6add204b45f15ff344ba6c92adedb0a Reviewed-by: Sergey Belyashov Reviewed-by: Alex Trotsenko Reviewed-by: Denis Shienkov --- src/serialport/qserialport_win.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index ae32fcf..46fc9d9 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -627,7 +627,8 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize) QObjectPrivate::connect(startAsyncWriteTimer, &QTimer::timeout, this, &QSerialPortPrivate::_q_startAsyncWrite); startAsyncWriteTimer->setSingleShot(true); } - startAsyncWriteTimer->start(0); + if (!startAsyncWriteTimer->isActive()) + startAsyncWriteTimer->start(); } return maxSize; } -- cgit v1.2.1 From bcb847285171cf63abe24f27c54fc309c54a4696 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 11 Jul 2016 12:33:40 +0300 Subject: QSerialPortInfo: Extract Method anyOfPort Change-Id: Ic0851ee8d491f29922d55f3c0530ccd21ed171a5 Reviewed-by: Denis Shienkov --- src/serialport/qserialportinfo_win.cpp | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp index 398666e..1bab3e9 100644 --- a/src/serialport/qserialportinfo_win.cpp +++ b/src/serialport/qserialportinfo_win.cpp @@ -187,23 +187,6 @@ static QString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInf return portName; } -class SerialPortNameEqualFunctor -{ -public: - explicit SerialPortNameEqualFunctor(const QString &serialPortName) - : m_serialPortName(serialPortName) - { - } - - bool operator() (const QSerialPortInfo &serialPortInfo) const - { - return serialPortInfo.portName() == m_serialPortName; - } - -private: - const QString &m_serialPortName; -}; - static QString deviceDescription(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) { @@ -288,6 +271,15 @@ static QString deviceSerialNumber(QString instanceIdentifier, return QString(); } +static bool anyOfPorts(const QList &ports, const QString &portName) +{ + const auto end = ports.end(); + auto isPortNamesEquals = [&portName](const QSerialPortInfo &portInfo) { + return portInfo.portName() == portName; + }; + return std::find_if(ports.begin(), end, isPortNamesEquals) != end; +} + QList QSerialPortInfo::availablePorts() { static const struct { @@ -318,10 +310,8 @@ QList QSerialPortInfo::availablePorts() if (portName.isEmpty() || portName.contains(QLatin1String("LPT"))) continue; - if (std::find_if(serialPortInfoList.begin(), serialPortInfoList.end(), - SerialPortNameEqualFunctor(portName)) != serialPortInfoList.end()) { + if (anyOfPorts(serialPortInfoList, portName)) continue; - } QSerialPortInfoPrivate priv; @@ -346,8 +336,7 @@ QList QSerialPortInfo::availablePorts() const auto portNames = portNamesFromHardwareDeviceMap(); for (const QString &portName : portNames) { - if (std::find_if(serialPortInfoList.cbegin(), serialPortInfoList.cend(), - SerialPortNameEqualFunctor(portName)) == serialPortInfoList.cend()) { + if (!anyOfPorts(serialPortInfoList, portName)) { QSerialPortInfoPrivate priv; priv.portName = portName; priv.device = QSerialPortInfoPrivate::portNameToSystemLocation(portName); -- cgit v1.2.1 From 7346857f4f675f57572d54f15cfad9111af2abde Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Sun, 10 Jul 2016 13:12:37 +0300 Subject: Remove mention of Windows CE support As Windows CE support has been stopped since Qt 5.7. Change-Id: I850c5e1e41508502a9e82491f89488facca40f51 Reviewed-by: Anton Kudryavtsev Reviewed-by: Sergey Belyashov Reviewed-by: Denis Shienkov --- src/serialport/qserialport.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp index d4e9a4f..f7656c5 100644 --- a/src/serialport/qserialport.cpp +++ b/src/serialport/qserialport.cpp @@ -514,10 +514,6 @@ void QSerialPort::setPort(const QSerialPortInfo &serialPortInfo) \li Windows \li Removes the prefix "\\\\.\\" or "//./" from the system location and returns the remainder of the string. - \row - \li Windows CE - \li Removes the suffix ":" from the system location - and returns the remainder of the string. \row \li Unix, BSD \li Removes the prefix "/dev/" from the system location @@ -650,9 +646,9 @@ bool QSerialPort::settingsRestoredOnClose() const after that the opening of the port succeeds. \warning Setting the AllDirections flag is supported on all platforms. - Windows and Windows CE support only this mode. + Windows supports only this mode. - \warning Returns equal baud rate in any direction on Windows, Windows CE. + \warning Returns equal baud rate in any direction on Windows. The default value is Baud9600, i.e. 9600 bits per second. */ -- cgit v1.2.1 From 133dbd59fb04974149d2140b267fce91a7cfd4a2 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Mon, 11 Jul 2016 16:58:29 +0300 Subject: Detach buffer's segment for asynchronous write operation QRingBuffer does not guarantee that the read pointer which is returned by QRingBuffer::readPointer() will stay valid after calling QRingBuffer::reserve() or QRingBuffer::append(). Thus, we need to detach the buffer's segment and pass it to the WriteFile() function to ensure it stays unmodified for the whole time of the asynchronous operation. Change-Id: I5a42086b4339a050a4df57c39348864502be2c74 Reviewed-by: Oswald Buddenhagen Reviewed-by: Alex Trotsenko Reviewed-by: Sergey Belyashov Reviewed-by: Anton Kudryavtsev Reviewed-by: Denis Shienkov --- src/serialport/qserialport.cpp | 9 +-------- src/serialport/qserialport_p.h | 2 +- src/serialport/qserialport_win.cpp | 22 +++++++++------------- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp index 481b07e..8b4449b 100644 --- a/src/serialport/qserialport.cpp +++ b/src/serialport/qserialport.cpp @@ -107,7 +107,6 @@ QSerialPortPrivate::QSerialPortPrivate() , startAsyncWriteTimer(0) , originalEventMask(0) , triggeredEventMask(0) - , actualBytesToWrite(0) #elif defined(Q_OS_UNIX) , descriptor(-1) , readNotifier(0) @@ -1260,13 +1259,7 @@ qint64 QSerialPort::bytesAvailable() const qint64 QSerialPort::bytesToWrite() const { Q_D(const QSerialPort); - qint64 bytes = QIODevice::bytesToWrite(); -#ifdef Q_OS_WIN32 - bytes += d->actualBytesToWrite; -#else - bytes += d->writeBuffer.size(); -#endif - return bytes; + return QIODevice::bytesToWrite() + d->writeBuffer.size(); } /*! diff --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h index 81febed..567ca19 100644 --- a/src/serialport/qserialport_p.h +++ b/src/serialport/qserialport_p.h @@ -224,6 +224,7 @@ public: COMMTIMEOUTS restoredCommTimeouts; HANDLE handle; QByteArray readChunkBuffer; + QByteArray writeChunkBuffer; bool communicationStarted; bool writeStarted; bool readStarted; @@ -234,7 +235,6 @@ public: OVERLAPPED writeCompletionOverlapped; DWORD originalEventMask; DWORD triggeredEventMask; - qint64 actualBytesToWrite; #elif defined(Q_OS_UNIX) diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index 1680d5a..056cc31 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -116,7 +116,6 @@ void QSerialPortPrivate::close() readStarted = false; writeStarted = false; writeBuffer.clear(); - actualBytesToWrite = 0; if (settingsRestoredOnClose) { ::SetCommState(handle, &restoredDcb); @@ -198,10 +197,8 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions) DWORD flags = 0; if (directions & QSerialPort::Input) flags |= PURGE_RXABORT | PURGE_RXCLEAR; - if (directions & QSerialPort::Output) { + if (directions & QSerialPort::Output) flags |= PURGE_TXABORT | PURGE_TXCLEAR; - actualBytesToWrite = 0; - } if (!::PurgeComm(handle, flags)) { setError(getSystemError()); return false; @@ -275,7 +272,7 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs) bool QSerialPortPrivate::waitForBytesWritten(int msecs) { - if (writeBuffer.isEmpty()) + if (writeBuffer.isEmpty() && writeChunkBuffer.isEmpty()) return false; if (!writeStarted && !_q_startAsyncWrite()) @@ -453,12 +450,13 @@ bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred) if (writeStarted) { if (bytesTransferred == qint64(-1)) { + writeChunkBuffer.clear(); writeStarted = false; return false; - } else if (bytesTransferred > 0) { - writeBuffer.free(bytesTransferred); - emit q->bytesWritten(bytesTransferred); } + Q_ASSERT(bytesTransferred == writeChunkBuffer.size()); + writeChunkBuffer.clear(); + emit q->bytesWritten(bytesTransferred); writeStarted = false; } @@ -525,10 +523,10 @@ bool QSerialPortPrivate::_q_startAsyncWrite() if (writeBuffer.isEmpty() || writeStarted) return true; - const int writeBytes = writeBuffer.nextDataBlockSize(); + writeChunkBuffer = writeBuffer.read(); ::ZeroMemory(&writeCompletionOverlapped, sizeof(writeCompletionOverlapped)); - if (!::WriteFile(handle, writeBuffer.readPointer(), - writeBytes, Q_NULLPTR, &writeCompletionOverlapped)) { + if (!::WriteFile(handle, writeChunkBuffer.constData(), + writeChunkBuffer.size(), Q_NULLPTR, &writeCompletionOverlapped)) { QSerialPortErrorInfo error = getSystemError(); if (error.errorCode != QSerialPort::NoError) { @@ -539,7 +537,6 @@ bool QSerialPortPrivate::_q_startAsyncWrite() } } - actualBytesToWrite -= writeBytes; writeStarted = true; return true; } @@ -574,7 +571,6 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize) Q_Q(QSerialPort); ::memcpy(writeBuffer.reserve(maxSize), data, maxSize); - actualBytesToWrite += maxSize; if (!writeBuffer.isEmpty() && !writeStarted) { if (!startAsyncWriteTimer) { -- cgit v1.2.1 From 7ef82ae562bab6b8bf7043d8e377eff60bb87b8a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 28 Jul 2016 13:51:16 +0200 Subject: Bump version Change-Id: I5c1304e43c8bfa07f53d397f7a90e84c6276a8bb --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 4ef7016..a2a0d41 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.7.0 +MODULE_VERSION = 5.7.1 -- cgit v1.2.1