diff options
-rw-r--r-- | config.tests/ntddmodm/main.cpp | 41 | ||||
-rw-r--r-- | config.tests/ntddmodm/ntddmodm.pro | 4 | ||||
-rw-r--r-- | qtserialport.pro | 3 | ||||
-rw-r--r-- | src/serialport/qserialport.cpp | 4 | ||||
-rw-r--r-- | src/serialport/qserialport_p.h | 4 | ||||
-rw-r--r-- | src/serialport/qserialport_unix.cpp | 18 | ||||
-rw-r--r-- | src/serialport/qserialport_win.cpp | 35 | ||||
-rw-r--r-- | src/serialport/qserialport_wince.cpp | 22 | ||||
-rw-r--r-- | src/serialport/qserialportinfo_unix.cpp | 3 | ||||
-rw-r--r-- | src/serialport/qserialportinfo_win.cpp | 52 | ||||
-rw-r--r-- | src/serialport/serialport-lib.pri | 2 | ||||
-rw-r--r-- | src/serialport/serialport.pro | 2 |
12 files changed, 103 insertions, 87 deletions
diff --git a/config.tests/ntddmodm/main.cpp b/config.tests/ntddmodm/main.cpp new file mode 100644 index 0000000..4bcb97f --- /dev/null +++ b/config.tests/ntddmodm/main.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 <windows.h> +#include <ntddmodm.h> + +int main(int, char**) +{ + GUID guid = GUID_DEVINTERFACE_MODEM; + return 0; +} diff --git a/config.tests/ntddmodm/ntddmodm.pro b/config.tests/ntddmodm/ntddmodm.pro new file mode 100644 index 0000000..abb9ba8 --- /dev/null +++ b/config.tests/ntddmodm/ntddmodm.pro @@ -0,0 +1,4 @@ +CONFIG -= qt +CONFIG += console + +SOURCES += main.cpp diff --git a/qtserialport.pro b/qtserialport.pro index b8e7231..95eb99b 100644 --- a/qtserialport.pro +++ b/qtserialport.pro @@ -6,4 +6,7 @@ lessThan(QT_MAJOR_VERSION, 5) { requires(!winrt) requires(!ios) +load(configure) +qtCompileTest(ntddmodm) + load(qt_parts) diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp index c64fba6..3469e80 100644 --- a/src/serialport/qserialport.cpp +++ b/src/serialport/qserialport.cpp @@ -655,8 +655,8 @@ bool QSerialPort::settingsRestoredOnClose() const setting is done automatically in the \l{QSerialPort::open()} method right after that the opening of the port succeeds. - \warning Setting the AllDirections flag is only supported on - the Windows, Windows CE platforms. + \warning Setting the AllDirections flag is supported on all platforms. + Windows and Windows CE support only this mode. \warning Returns equal baud rate in any direction on Windows, Windows CE. diff --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h index 4d37254..29c1d5a 100644 --- a/src/serialport/qserialport_p.h +++ b/src/serialport/qserialport_p.h @@ -159,7 +159,9 @@ public: static QString portNameToSystemLocation(const QString &port); static QString portNameFromSystemLocation(const QString &location); +#if defined(Q_OS_UNIX) static qint32 settingFromBaudRate(qint32 baudRate); +#endif static QList<qint32> standardBaudRates(); @@ -180,7 +182,6 @@ public: bool initialize(DWORD eventMask); bool updateDcb(); - bool updateCommTimeouts(); bool waitForReadOrWrite(bool *selectForRead, bool *selectForWrite, bool checkRead, bool checkWrite, @@ -203,7 +204,6 @@ public: bool initialize(); bool setDcb(DCB *dcb); bool getDcb(DCB *dcb); - bool updateCommTimeouts(); OVERLAPPED *waitForNotified(int msecs); bool completeAsyncCommunication(qint64 bytesTransferred); diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index 7eb43a1..7153449 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -237,14 +237,11 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) void QSerialPortPrivate::close() { - if (settingsRestoredOnClose) { - if (::tcsetattr(descriptor, TCSANOW, &restoredTermios) == -1) - setError(getSystemError()); - } + if (settingsRestoredOnClose) + ::tcsetattr(descriptor, TCSANOW, &restoredTermios); #ifdef TIOCNXCL - if (::ioctl(descriptor, TIOCNXCL) == -1) - setError(getSystemError()); + ::ioctl(descriptor, TIOCNXCL); #endif if (readNotifier) { @@ -257,8 +254,7 @@ void QSerialPortPrivate::close() writeNotifier = Q_NULLPTR; } - if (qt_safe_close(descriptor) == -1) - setError(getSystemError()); + qt_safe_close(descriptor); lockFileScopedPointer.reset(Q_NULLPTR); @@ -524,10 +520,10 @@ bool QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directi } if (serial.custom_divisor * baudRate != serial.baud_base) { - qWarning("Baud rate of serial port %s is set to %d instead of %d: divisor %f unsupported", + qWarning("Baud rate of serial port %s is set to %f instead of %d: divisor %f unsupported", qPrintable(systemLocation), - serial.baud_base / serial.custom_divisor, - baudRate, (float)serial.baud_base / baudRate); + float(serial.baud_base) / serial.custom_divisor, + baudRate, float(serial.baud_base) / baudRate); } if (::ioctl(descriptor, TIOCSSERIAL, &serial) == -1) { diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index 8e7c278..6d5dac0 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -104,8 +104,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) void QSerialPortPrivate::close() { - if (!::CancelIo(handle)) - setError(getSystemError()); + ::CancelIo(handle); if (notifier) { delete notifier; @@ -124,15 +123,11 @@ void QSerialPortPrivate::close() actualBytesToWrite = 0; if (settingsRestoredOnClose) { - if (!::SetCommState(handle, &restoredDcb)) - setError(getSystemError()); - else if (!::SetCommTimeouts(handle, &restoredCommTimeouts)) - setError(getSystemError()); + ::SetCommState(handle, &restoredDcb); + ::SetCommTimeouts(handle, &restoredCommTimeouts); } - if (!::CloseHandle(handle)) - setError(getSystemError()); - + ::CloseHandle(handle); handle = INVALID_HANDLE_VALUE; } @@ -636,8 +631,10 @@ inline bool QSerialPortPrivate::initialize() ::ZeroMemory(¤tCommTimeouts, sizeof(currentCommTimeouts)); currentCommTimeouts.ReadIntervalTimeout = MAXDWORD; - if (!updateCommTimeouts()) + if (!::SetCommTimeouts(handle, ¤tCommTimeouts)) { + setError(getSystemError()); return false; + } if (!::SetCommMask(handle, originalEventMask)) { setError(getSystemError()); @@ -677,15 +674,6 @@ bool QSerialPortPrivate::getDcb(DCB *dcb) return true; } -bool QSerialPortPrivate::updateCommTimeouts() -{ - if (!::SetCommTimeouts(handle, ¤tCommTimeouts)) { - setError(getSystemError()); - return false; - } - return true; -} - QSerialPortErrorInfo QSerialPortPrivate::getSystemError(int systemErrorCode) const { if (systemErrorCode == -1) @@ -813,15 +801,6 @@ static const QList<qint32> standardBaudRatePairList() return standardBaudRatesTable; }; -qint32 QSerialPortPrivate::settingFromBaudRate(qint32 baudRate) -{ - const QList<qint32> baudRatePairList = standardBaudRatePairList(); - const QList<qint32>::const_iterator baudRatePairListConstIterator - = std::find(baudRatePairList.constBegin(), baudRatePairList.constEnd(), baudRate); - - return (baudRatePairListConstIterator != baudRatePairList.constEnd()) ? *baudRatePairListConstIterator : 0; -} - QList<qint32> QSerialPortPrivate::standardBaudRates() { return standardBaudRatePairList(); diff --git a/src/serialport/qserialport_wince.cpp b/src/serialport/qserialport_wince.cpp index b1975af..6b063e1 100644 --- a/src/serialport/qserialport_wince.cpp +++ b/src/serialport/qserialport_wince.cpp @@ -559,8 +559,10 @@ inline bool QSerialPortPrivate::initialize(DWORD eventMask) ::memset(¤tCommTimeouts, 0, sizeof(currentCommTimeouts)); currentCommTimeouts.ReadIntervalTimeout = MAXDWORD; - if (!updateCommTimeouts()) + if (!::SetCommTimeouts(handle, ¤tCommTimeouts)) { + setError(getSystemError()); return false; + } eventNotifier = new CommEventNotifier(eventMask, this, q); eventNotifier->start(); @@ -589,15 +591,6 @@ bool QSerialPortPrivate::updateDcb() return ret; } -bool QSerialPortPrivate::updateCommTimeouts() -{ - if (!::SetCommTimeouts(handle, ¤tCommTimeouts)) { - setError(getSystemError()); - return false; - } - return true; -} - QSerialPortErrorInfo QSerialPortPrivate::getSystemError(int systemErrorCode) const { if (systemErrorCode == -1) @@ -743,15 +736,6 @@ static const QList<qint32> standardBaudRatePairList() return standardBaudRatesTable; }; -qint32 QSerialPortPrivate::settingFromBaudRate(qint32 baudRate) -{ - const QList<qint32> baudRatePairList = standardBaudRatePairList(); - const QList<qint32>::const_iterator baudRatePairListConstIterator - = std::find(baudRatePairList.constBegin(), baudRatePairList.constEnd(), baudRate); - - return (baudRatePairListConstIterator != baudRatePairList.constEnd()) ? *baudRatePairListConstIterator : 0; -} - QList<qint32> QSerialPortPrivate::standardBaudRates() { return standardBaudRatePairList(); diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp index f52516f..f5bbfc6 100644 --- a/src/serialport/qserialportinfo_unix.cpp +++ b/src/serialport/qserialportinfo_unix.cpp @@ -74,6 +74,7 @@ static QStringList filteredDeviceFilePaths() << QStringLiteral("ttyMI*") // MOXA pci/serial converters. << QStringLiteral("ttymxc*") // Motorola IMX serial ports (i.e. Freescale i.MX). << QStringLiteral("ttyAMA*") // AMBA serial device for embedded platform on ARM (i.e. Raspberry Pi). + << QStringLiteral("ttyTHS*") // Serial device for embedded platform on ARM (i.e. Tegra Jetson TK1). << QStringLiteral("rfcomm*") // Bluetooth serial device. << QStringLiteral("ircomm*") // IrDA serial device. << QStringLiteral("tnt*"); // Virtual tty0tty serial device. @@ -704,7 +705,7 @@ QList<QSerialPortInfo> availablePortsByUdev(bool &ok) if (parentdev) { const QString driverName = deviceDriver(parentdev); - if (isSerial8250Driver(driverName) && !isValidSerial8250(priv.portName)) + if (isSerial8250Driver(driverName) && !isValidSerial8250(priv.device)) continue; priv.description = deviceDescription(dev.data()); priv.manufacturer = deviceManufacturer(dev.data()); diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp index 06987f2..63cf642 100644 --- a/src/serialport/qserialportinfo_win.cpp +++ b/src/serialport/qserialportinfo_win.cpp @@ -44,26 +44,18 @@ #include <vector> #include <initguid.h> +#include <devguid.h> // for GUID_DEVCLASS_PORTS and GUID_DEVCLASS_MODEM +#include <winioctl.h> // for GUID_DEVINTERFACE_COMPORT #include <setupapi.h> #include <cfgmgr32.h> -QT_BEGIN_NAMESPACE - -typedef QPair<QUuid, DWORD> GuidFlagsPair; +#ifdef QT_NO_REDEFINE_GUID_DEVINTERFACE_MODEM +# include <ntddmodm.h> // for GUID_DEVINTERFACE_MODEM +#else + DEFINE_GUID(GUID_DEVINTERFACE_MODEM, 0x2c7089aa, 0x2e0e, 0x11d1, 0xb1, 0x14, 0x00, 0xc0, 0x4f, 0xc2, 0xaa, 0xe4); +#endif -static inline const QList<GuidFlagsPair>& guidFlagsPairs() -{ - static const QList<GuidFlagsPair> guidFlagsPairList = QList<GuidFlagsPair>() - // Standard Setup Ports Class GUID - << qMakePair(QUuid(0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18), DWORD(DIGCF_PRESENT)) - // Standard Setup Modems Class GUID - << qMakePair(QUuid(0x4D36E96D, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18), DWORD(DIGCF_PRESENT)) - // Standard Serial Port Device Interface Class GUID - << qMakePair(QUuid(0x86E0D1E0, 0x8089, 0x11D0, 0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73), DWORD(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) - // Standard Modem Device Interface Class GUID - << qMakePair(QUuid(0x2C7089AA, 0x2E0E, 0x11D1, 0xB1, 0x14, 0x00, 0xC0, 0x4F, 0xC2, 0xAA, 0xE4), DWORD(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); - return guidFlagsPairList; -} +QT_BEGIN_NAMESPACE static QStringList portNamesFromHardwareDeviceMap() { @@ -155,17 +147,20 @@ static QString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInf if (key == INVALID_HANDLE_VALUE) return QString(); - static const QStringList portNameRegistryKeyList = QStringList() - << QStringLiteral("PortName") - << QStringLiteral("PortNumber"); + static const wchar_t * const keyTokens[] = { + L"PortName\0", + L"PortNumber\0" + }; + + static const int keyTokensCount = sizeof(keyTokens) / sizeof(keyTokens[0]); QString portName; - foreach (const QString &portNameKey, portNameRegistryKeyList) { + for (int i = 0; i < keyTokensCount; ++i) { DWORD dataType = 0; std::vector<wchar_t> outputBuffer(MAX_PATH + 1, 0); DWORD bytesRequired = MAX_PATH; forever { - const LONG ret = ::RegQueryValueEx(key, reinterpret_cast<const wchar_t *>(portNameKey.utf16()), Q_NULLPTR, &dataType, + const LONG ret = ::RegQueryValueEx(key, keyTokens[i], Q_NULLPTR, &dataType, reinterpret_cast<PBYTE>(&outputBuffer[0]), &bytesRequired); if (ret == ERROR_MORE_DATA) { outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0); @@ -283,10 +278,21 @@ static QString deviceSerialNumber(const QString &instanceIdentifier, QList<QSerialPortInfo> QSerialPortInfo::availablePorts() { + static const struct { + GUID guid; DWORD flags; + } setupTokens[] = { + { GUID_DEVCLASS_PORTS, DIGCF_PRESENT }, + { GUID_DEVCLASS_MODEM, DIGCF_PRESENT }, + { GUID_DEVINTERFACE_COMPORT, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE }, + { GUID_DEVINTERFACE_MODEM, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE } + }; + + static const int setupTokensCount = sizeof(setupTokens) / sizeof(setupTokens[0]); + QList<QSerialPortInfo> serialPortInfoList; - foreach (const GuidFlagsPair &uniquePair, guidFlagsPairs()) { - const HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(reinterpret_cast<const GUID *>(&uniquePair.first), Q_NULLPTR, Q_NULLPTR, uniquePair.second); + for (int i = 0; i < setupTokensCount; ++i) { + const HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(&setupTokens[i].guid, Q_NULLPTR, Q_NULLPTR, setupTokens[i].flags); if (deviceInfoSet == INVALID_HANDLE_VALUE) return serialPortInfoList; diff --git a/src/serialport/serialport-lib.pri b/src/serialport/serialport-lib.pri index c7826ef..c3b00ea 100644 --- a/src/serialport/serialport-lib.pri +++ b/src/serialport/serialport-lib.pri @@ -33,7 +33,7 @@ wince* { $$PWD/qserialportinfo_wince.cpp } -unix:!symbian { +unix { SOURCES += \ $$PWD/qserialport_unix.cpp diff --git a/src/serialport/serialport.pro b/src/serialport/serialport.pro index 40c0339..92d0795 100644 --- a/src/serialport/serialport.pro +++ b/src/serialport/serialport.pro @@ -3,6 +3,8 @@ QT = core-private QMAKE_DOCS = $$PWD/doc/qtserialport.qdocconf +config_ntddmodm: DEFINES += QT_NO_REDEFINE_GUID_DEVINTERFACE_MODEM + load(qt_module) include($$PWD/serialport-lib.pri) |