summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/serialport/doc/blockingslave.qdoc2
-rw-r--r--examples/serialport/doc/terminal.qdoc2
-rw-r--r--src/serialport/qserialport.cpp64
-rw-r--r--src/serialport/qserialport.h6
-rw-r--r--src/serialport/qserialport_symbian.cpp14
-rw-r--r--src/serialport/qserialport_symbian_p.h5
-rw-r--r--src/serialport/qserialport_unix.cpp98
-rw-r--r--src/serialport/qserialport_unix_p.h5
-rw-r--r--src/serialport/qserialport_win.cpp336
-rw-r--r--src/serialport/qserialport_win_p.h21
-rw-r--r--src/serialport/qserialport_wince.cpp70
-rw-r--r--src/serialport/qserialportinfo_unix.cpp112
-rw-r--r--src/serialport/qserialportinfo_win.cpp89
14 files changed, 433 insertions, 393 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 45d05b25..5d8fd36b 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,3 +1,3 @@
load(qt_build_config)
-MODULE_VERSION = 5.2.1
+MODULE_VERSION = 5.2.2
diff --git a/examples/serialport/doc/blockingslave.qdoc b/examples/serialport/doc/blockingslave.qdoc
index c98080d9..df35bfc0 100644
--- a/examples/serialport/doc/blockingslave.qdoc
+++ b/examples/serialport/doc/blockingslave.qdoc
@@ -62,7 +62,7 @@
leads to simpler code, but because of its blocking behavior, it should only
be used in non-GUI threads to prevent the user interface from freezing.
But contrary to what many think, using threads with QThread does not
- necessarily add unmanagable complexity to your application.
+ necessarily add unmanageable complexity to your application.
This application is a Slave, that demonstrate the work paired with Master
application \l{Blocking Master Example}.
diff --git a/examples/serialport/doc/terminal.qdoc b/examples/serialport/doc/terminal.qdoc
index e74e237d..ed8fa023 100644
--- a/examples/serialport/doc/terminal.qdoc
+++ b/examples/serialport/doc/terminal.qdoc
@@ -82,7 +82,7 @@
The serial port is instantiated in the \l{terminal/mainwindow.cpp}{MainWindow}
constructor. The main widget is passed as the parent, so the object deletion
- happens automatically according to the the parent and child mechanism in Qt:
+ happens automatically according to the parent and child mechanism in Qt:
\snippet terminal/mainwindow.cpp 0
\dots
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp
index aa9b616b..060fcdc6 100644
--- a/src/serialport/qserialport.cpp
+++ b/src/serialport/qserialport.cpp
@@ -212,12 +212,12 @@ int QSerialPortPrivateData::timeoutValue(int msecs, int elapsed)
\value Data5 The number of data bits in each character is 5. It
is used for Baudot code. It generally only makes
- sense with older equipments such as teleprinters.
+ sense with older equipment such as teleprinters.
\value Data6 The number of data bits in each character is 6. It
is rarely used.
\value Data7 The number of data bits in each character is 7. It
is used for true ASCII. It generally only makes
- sense with older equipments such as teleprinters.
+ sense with older equipment such as teleprinters.
\value Data8 The number of data bits in each character is 8. It
is used for most kinds of data, as this size matches
the size of a byte. It is almost universally used in
@@ -261,9 +261,9 @@ int QSerialPortPrivateData::timeoutValue(int msecs, int elapsed)
This enum describes the number of stop bits used.
\value OneStop 1 stop bit.
- \value OneAndHalfStop 1.5 stop bits. This is only for Windows platform.
+ \value OneAndHalfStop 1.5 stop bits. This is only for the Windows platform.
\value TwoStop 2 stop bits.
- \value UnknownStopBits Unknown number of stop bit. This value is obsolete.
+ \value UnknownStopBits Unknown number of stop bits. This value is obsolete.
It is provided to keep old source code working. We
strongly advise against using it in new code.
@@ -320,7 +320,7 @@ int QSerialPortPrivateData::timeoutValue(int msecs, int elapsed)
while parity errors were detected.
\value SkipPolicy Skips the bad character.
- \value PassZeroPolicy Replaces bad character to zero.
+ \value PassZeroPolicy Replaces bad character with zero.
\value IgnorePolicy Ignores the error for a bad character.
\value StopReceivingPolicy Stops data reception on error.
\value UnknownPolicy Unknown policy.
@@ -428,7 +428,7 @@ QSerialPort::~QSerialPort()
/*!
Sets the \a name of the serial port.
- The name of the serial port can be passed on as either a short name or
+ The name of the serial port can be passed as either a short name or
the long system location if necessary.
\sa portName(), QSerialPortInfo
@@ -451,9 +451,9 @@ void QSerialPort::setPort(const QSerialPortInfo &serialPortInfo)
}
/*!
- Returns the name set by setPort() or to the QSerialPort constructors.
- This name is short, i.e. it extract and convert out from the internal
- variable system location of the device. Conversion algorithm is
+ Returns the name set by setPort() or passed to the QSerialPort constructor.
+ This name is short, i.e. it is extracted and converted from the internal
+ variable system location of the device. The conversion algorithm is
platform specific:
\table
\header
@@ -465,7 +465,7 @@ void QSerialPort::setPort(const QSerialPortInfo &serialPortInfo)
and returns the remainder of the string.
\row
\li Windows CE
- \li Removes the postfix ":" from the system location
+ \li Removes the suffix ":" from the system location
and returns the remainder of the string.
\row
\li Symbian
@@ -500,7 +500,7 @@ QString QSerialPort::portName() const
obtained by calling the error() method.
\note This method has to be called before setting certain serial port
- parameters. See each property documentation for details when it is
+ parameters. See each property documentation for the details of when it is
necessary.
\warning The \a mode has to be QIODevice::ReadOnly, QIODevice::WriteOnly,
@@ -558,11 +558,11 @@ void QSerialPort::close()
/*!
\property QSerialPort::settingsRestoredOnClose
- \brief the flag which allows to restore the previous settings while closing
+ \brief the flag which specifies to restore the previous settings when closing
the serial port.
If this flag is true, the settings will be restored; otherwise not.
- The default state of the QSerialPort class is configured to restore the
+ The default state of the QSerialPort class is to restore the
settings.
*/
void QSerialPort::setSettingsRestoredOnClose(bool restore)
@@ -584,9 +584,9 @@ bool QSerialPort::settingsRestoredOnClose() const
/*!
\fn void QSerialPort::settingsRestoredOnCloseChanged(bool restore)
- This signal is emitted after the flag which allows to restore the
+ This signal is emitted after the flag which specifies to restore the
previous settings while closing the serial port has been changed. The new
- flag which allows to restore the previous settings while closing the serial
+ flag which specifies to restore the previous settings while closing the serial
port is passed as \a restore.
\sa QSerialPort::settingsRestoredOnClose
@@ -608,8 +608,8 @@ bool QSerialPort::settingsRestoredOnClose() const
with the kernel and hardware. Hence, the two scenarios cannot be completely
compared to each other.
- \warning Only the AllDirections flag is support for setting this property on
- Windows, Windows CE, and Symbian.
+ \warning Setting the AllDirections flag is only supported on
+ the Windows, Windows CE, and Symbian platforms.
\warning Returns equal baud rate in any direction on Windows, Windows CE, and
Symbian.
@@ -1034,7 +1034,7 @@ bool QSerialPort::flush()
/*!
Discards all characters from the output or input buffer, depending on
- given directions \a directions. Including clear an internal class buffers and
+ given directions \a directions. This includes clearing the internal class buffers and
the UART (driver) buffers. Also terminate pending read or write operations.
If successful, returns true; otherwise returns false.
@@ -1088,8 +1088,8 @@ bool QSerialPort::atEnd() const
/*!
\property QSerialPort::dataErrorPolicy
- \brief the error policy how the process receives the character in case of
- parity error detection.
+ \brief the error policy for how the process receives characters in the case where
+ a parity error is detected.
\obsolete
If the setting is successful, returns true; otherwise returns false. The
@@ -1131,9 +1131,9 @@ QSerialPort::DataErrorPolicy QSerialPort::dataErrorPolicy() const
\fn void QSerialPort::dataErrorPolicyChanged(DataErrorPolicy policy)
\obsolete
- This signal is emitted after the error policy how the process receives the
- character in case of parity error detection has been changed. The new error
- policy how the process receives the character in case of parity error
+ This signal is emitted after the error policy for how the process receives
+ characters in case of parity error detection has been changed. The new error
+ policy for how the process receives the character in case of parity error
detection is passed as \a policy.
\sa QSerialPort::dataErrorPolicy
@@ -1164,8 +1164,8 @@ void QSerialPort::clearError()
/*!
\fn void QSerialPort::error(SerialPortError error)
- This signal is emitted after the error has been changed. The new erroris
- passed as \a error.
+ This signal is emitted after the error has been changed. The new error
+ is passed as \a error.
\sa QSerialPort::error
*/
@@ -1191,14 +1191,14 @@ qint64 QSerialPort::readBufferSize() const
size bytes.
If the buffer size is limited to a certain size, QSerialPort
- will not buffer more than this size of data. Exceptionally, a buffer
+ will not buffer more than this size of data. The special case of a buffer
size of 0 means that the read buffer is unlimited and all
incoming data is buffered. This is the default.
This option is useful if the data is only read at certain points
in time (for instance in a real-time streaming application) or if the serial
port should be protected against receiving too much data, which may
- eventually causes that the application runs out of memory.
+ eventually cause the application to run out of memory.
\sa readBufferSize(), read()
*/
@@ -1287,8 +1287,8 @@ bool QSerialPort::waitForReadyRead(int msecs)
\fn Handle QSerialPort::handle() const
\since 5.2
- Returns the native serial port descriptor of the object. If the serial port
- is not open or the platform is not supported, handle() returns -1.
+ If the platform is supported and the serial port is open, returns the native
+ serial port handle; otherwise returns -1.
\warning This function is for expert use only; use it at your own risk.
Furthermore, this function carries no compatibility promise between minor
@@ -1380,7 +1380,11 @@ qint64 QSerialPort::readLineData(char *data, qint64 maxSize)
qint64 QSerialPort::writeData(const char *data, qint64 maxSize)
{
Q_D(QSerialPort);
- return d->writeToBuffer(data, maxSize);
+
+ ::memcpy(d->writeBuffer.reserve(maxSize), data, maxSize);
+ if (!d->writeBuffer.isEmpty())
+ d->startWriting();
+ return maxSize;
}
void QSerialPort::setError(QSerialPort::SerialPortError serialPortError, const QString &errorString)
diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h
index 795cf33d..30e3b8c1 100644
--- a/src/serialport/qserialport.h
+++ b/src/serialport/qserialport.h
@@ -278,9 +278,9 @@ private:
Q_DISABLE_COPY(QSerialPort)
#if defined (Q_OS_WIN32) || defined(Q_OS_WIN64)
- Q_PRIVATE_SLOT(d_func(), void _q_canCompleteCommunication())
- Q_PRIVATE_SLOT(d_func(), void _q_canCompleteRead())
- Q_PRIVATE_SLOT(d_func(), void _q_canCompleteWrite())
+ Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncCommunication())
+ Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncRead())
+ Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncWrite())
#endif
};
diff --git a/src/serialport/qserialport_symbian.cpp b/src/serialport/qserialport_symbian.cpp
index 60477934..b904d2be 100644
--- a/src/serialport/qserialport_symbian.cpp
+++ b/src/serialport/qserialport_symbian.cpp
@@ -237,21 +237,9 @@ bool QSerialPortPrivate::setBreakEnabled(bool set)
return false;
}
-qint64 QSerialPortPrivate::systemInputQueueSize () const
-{
- return descriptor.QueryReceiveBuffer();
-}
-
-qint64 QSerialPortPrivate::systemOutputQueueSize () const
-{
- // TODO: Implement me
- return 0;
-}
-
-qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize)
+void QSerialPortPrivate::startWriting()
{
// TODO: Implement me
- return -1;
}
bool QSerialPortPrivate::waitForReadyRead(int msec)
diff --git a/src/serialport/qserialport_symbian_p.h b/src/serialport/qserialport_symbian_p.h
index 253aa11d..5d95ca95 100644
--- a/src/serialport/qserialport_symbian_p.h
+++ b/src/serialport/qserialport_symbian_p.h
@@ -69,10 +69,7 @@ public:
bool sendBreak(int duration);
bool setBreakEnabled(bool set);
- qint64 systemInputQueueSize () const;
- qint64 systemOutputQueueSize () const;
-
- qint64 writeToBuffer(const char *data, qint64 maxSize);
+ void startWriting();
bool waitForReadyRead(int msec);
bool waitForBytesWritten(int msec);
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index 95717673..a904c06a 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -227,7 +227,8 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
}
#ifdef TIOCEXCL
- ::ioctl(descriptor, TIOCEXCL);
+ if (::ioctl(descriptor, TIOCEXCL) == -1)
+ q->setError(decodeSystemError());
#endif
if (::tcgetattr(descriptor, &restoredTermios) == -1) {
@@ -258,16 +259,23 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
void QSerialPortPrivate::close()
{
+ Q_Q(QSerialPort);
+
if (settingsRestoredOnClose) {
- ::tcsetattr(descriptor, TCSANOW, &restoredTermios);
+ if (::tcsetattr(descriptor, TCSANOW, &restoredTermios) == -1)
+ q->setError(decodeSystemError());
+
#ifdef Q_OS_LINUX
- if (isCustomBaudRateSupported)
- ::ioctl(descriptor, TIOCSSERIAL, &restoredSerialInfo);
+ if (isCustomBaudRateSupported) {
+ if (::ioctl(descriptor, TIOCSSERIAL, &restoredSerialInfo) == -1)
+ q->setError(decodeSystemError());
+ }
#endif
}
#ifdef TIOCNXCL
- ::ioctl(descriptor, TIOCNXCL);
+ if (::ioctl(descriptor, TIOCNXCL) == -1)
+ q->setError(decodeSystemError());
#endif
if (readNotifier) {
@@ -288,7 +296,8 @@ void QSerialPortPrivate::close()
exceptionNotifier = 0;
}
- ::close(descriptor);
+ if (::close(descriptor) == -1)
+ q->setError(decodeSystemError());
if (lockFileScopedPointer->isLocked())
lockFileScopedPointer->unlock();
@@ -358,14 +367,28 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
bool QSerialPortPrivate::setDataTerminalReady(bool set)
{
+ Q_Q(QSerialPort);
+
int status = TIOCM_DTR;
- return ::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) != -1;
+ if (::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) == -1) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+
+ return true;
}
bool QSerialPortPrivate::setRequestToSend(bool set)
{
+ Q_Q(QSerialPort);
+
int status = TIOCM_RTS;
- return ::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) != -1;
+ if (::ioctl(descriptor, set ? TIOCMBIS : TIOCMBIC, &status) == -1) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+
+ return true;
}
bool QSerialPortPrivate::flush()
@@ -380,54 +403,45 @@ bool QSerialPortPrivate::flush()
bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
{
- return ::tcflush(descriptor, (directions == QSerialPort::AllDirections)
- ? TCIOFLUSH : (directions & QSerialPort::Input) ? TCIFLUSH : TCOFLUSH) != -1;
+ Q_Q(QSerialPort);
+
+ if (::tcflush(descriptor, (directions == QSerialPort::AllDirections)
+ ? TCIOFLUSH : (directions & QSerialPort::Input) ? TCIFLUSH : TCOFLUSH) == -1) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+
+ return true;
}
bool QSerialPortPrivate::sendBreak(int duration)
{
- return ::tcsendbreak(descriptor, duration) != -1;
+ Q_Q(QSerialPort);
+
+ if (::tcsendbreak(descriptor, duration) == -1) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+
+ return true;
}
bool QSerialPortPrivate::setBreakEnabled(bool set)
{
- return ::ioctl(descriptor, set ? TIOCSBRK : TIOCCBRK) != -1;
-}
+ Q_Q(QSerialPort);
-qint64 QSerialPortPrivate::systemInputQueueSize () const
-{
- int nbytes = 0;
-#ifdef TIOCINQ
- if (::ioctl(descriptor, TIOCINQ, &nbytes) == -1)
- return -1;
-#endif
- return nbytes;
-}
+ if (::ioctl(descriptor, set ? TIOCSBRK : TIOCCBRK) == -1) {
+ q->setError(decodeSystemError());
+ return false;
+ }
-qint64 QSerialPortPrivate::systemOutputQueueSize () const
-{
- int nbytes = 0;
-#ifdef TIOCOUTQ
- if (::ioctl(descriptor, TIOCOUTQ, &nbytes) == -1)
- return -1;
-#endif
- return nbytes;
+ return true;
}
-qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize)
+void QSerialPortPrivate::startWriting()
{
- char *ptr = writeBuffer.reserve(maxSize);
- if (maxSize == 1)
- *ptr = *data;
- else
- ::memcpy(ptr, data, maxSize);
-
- const qint64 written = maxSize;
-
- if (!writeBuffer.isEmpty() && !isWriteNotificationEnabled())
+ if (!isWriteNotificationEnabled())
setWriteNotificationEnabled(true);
-
- return written;
}
bool QSerialPortPrivate::waitForReadyRead(int msecs)
diff --git a/src/serialport/qserialport_unix_p.h b/src/serialport/qserialport_unix_p.h
index dba0ac55..1960316a 100644
--- a/src/serialport/qserialport_unix_p.h
+++ b/src/serialport/qserialport_unix_p.h
@@ -108,10 +108,7 @@ public:
bool sendBreak(int duration);
bool setBreakEnabled(bool set);
- qint64 systemInputQueueSize () const;
- qint64 systemOutputQueueSize () const;
-
- qint64 writeToBuffer(const char *data, qint64 maxSize);
+ void startWriting();
bool waitForReadyRead(int msecs);
bool waitForBytesWritten(int msecs);
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index 4a72da05..ecf8a62f 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -98,11 +98,11 @@ static void initializeOverlappedStructure(OVERLAPPED &overlapped)
QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
: QSerialPortPrivateData(q)
- , descriptor(INVALID_HANDLE_VALUE)
+ , handle(INVALID_HANDLE_VALUE)
, parityErrorOccurred(false)
, readChunkBuffer(ReadChunkSize, 0)
, readyReadEmitted(0)
- , writeSequenceStarted(false)
+ , writeStarted(false)
, communicationNotifier(new QWinEventNotifier(q))
, readCompletionNotifier(new QWinEventNotifier(q))
, writeCompletionNotifier(new QWinEventNotifier(q))
@@ -115,7 +115,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
q->setError(decodeSystemError());
else {
communicationNotifier->setHandle(communicationOverlapped.hEvent);
- q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteCommunication()));
+ q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncCommunication()));
}
::ZeroMemory(&readCompletionOverlapped, sizeof(readCompletionOverlapped));
@@ -124,7 +124,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
q->setError(decodeSystemError());
else {
readCompletionNotifier->setHandle(readCompletionOverlapped.hEvent);
- q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteRead()));
+ q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncRead()));
}
::ZeroMemory(&writeCompletionOverlapped, sizeof(writeCompletionOverlapped));
@@ -133,7 +133,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
q->setError(decodeSystemError());
else {
writeCompletionNotifier->setHandle(writeCompletionOverlapped.hEvent);
- q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteWrite()));
+ q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncWrite()));
}
}
@@ -151,15 +151,18 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
if (mode & QIODevice::WriteOnly)
desiredAccess |= GENERIC_WRITE;
- descriptor = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation.utf16()),
+ handle = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation.utf16()),
desiredAccess, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (descriptor == INVALID_HANDLE_VALUE) {
+ if (handle == INVALID_HANDLE_VALUE) {
q->setError(decodeSystemError());
return false;
}
- if (!::GetCommState(descriptor, &restoredDcb)) {
+ ::ZeroMemory(&restoredDcb, sizeof(restoredDcb));
+ restoredDcb.DCBlength = sizeof(restoredDcb);
+
+ if (!::GetCommState(handle, &restoredDcb)) {
q->setError(decodeSystemError());
return false;
}
@@ -172,10 +175,13 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
currentDcb.fNull = FALSE;
currentDcb.fErrorChar = FALSE;
+ if (currentDcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
+ currentDcb.fDtrControl = DTR_CONTROL_DISABLE;
+
if (!updateDcb())
return false;
- if (!::GetCommTimeouts(descriptor, &restoredCommTimeouts)) {
+ if (!::GetCommTimeouts(handle, &restoredCommTimeouts)) {
q->setError(decodeSystemError());
return false;
}
@@ -192,19 +198,13 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
if (mode & QIODevice::WriteOnly)
writeCompletionNotifier->setEnabled(true);
- if (!::SetCommMask(descriptor, originalEventMask)) {
+ if (!::SetCommMask(handle, originalEventMask)) {
q->setError(decodeSystemError());
return false;
}
- initializeOverlappedStructure(communicationOverlapped);
- if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) {
- const QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- q->setError(decodeSystemError());
- return false;
- }
- }
+ if (!startAsyncCommunication())
+ return false;
communicationNotifier->setEnabled(true);
@@ -216,7 +216,7 @@ void QSerialPortPrivate::close()
{
Q_Q(QSerialPort);
- if (!::CancelIo(descriptor))
+ if (!::CancelIo(handle))
q->setError(decodeSystemError());
readCompletionNotifier->setEnabled(false);
@@ -225,23 +225,23 @@ void QSerialPortPrivate::close()
readBuffer.clear();
- writeSequenceStarted = false;
+ writeStarted = false;
writeBuffer.clear();
readyReadEmitted = false;
parityErrorOccurred = false;
if (settingsRestoredOnClose) {
- if (!::SetCommState(descriptor, &restoredDcb))
+ if (!::SetCommState(handle, &restoredDcb))
q->setError(decodeSystemError());
- else if (!::SetCommTimeouts(descriptor, &restoredCommTimeouts))
+ else if (!::SetCommTimeouts(handle, &restoredCommTimeouts))
q->setError(decodeSystemError());
}
- if (!::CloseHandle(descriptor))
+ if (!::CloseHandle(handle))
q->setError(decodeSystemError());
- descriptor = INVALID_HANDLE_VALUE;
+ handle = INVALID_HANDLE_VALUE;
}
#endif // #ifndef Q_OS_WINCE
@@ -252,7 +252,7 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
DWORD modemStat = 0;
- if (!::GetCommModemStatus(descriptor, &modemStat)) {
+ if (!::GetCommModemStatus(handle, &modemStat)) {
q->setError(decodeSystemError());
return QSerialPort::NoSignal;
}
@@ -269,9 +269,10 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
ret |= QSerialPort::DataCarrierDetectSignal;
DWORD bytesReturned = 0;
- if (!::DeviceIoControl(descriptor, IOCTL_SERIAL_GET_DTRRTS, NULL, 0,
+ if (!::DeviceIoControl(handle, IOCTL_SERIAL_GET_DTRRTS, NULL, 0,
&modemStat, sizeof(modemStat),
&bytesReturned, NULL)) {
+ q->setError(decodeSystemError());
return ret;
}
@@ -285,93 +286,88 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
bool QSerialPortPrivate::setDataTerminalReady(bool set)
{
- return ::EscapeCommFunction(descriptor, set ? SETDTR : CLRDTR);
+ Q_Q(QSerialPort);
+
+ if (!::EscapeCommFunction(handle, set ? SETDTR : CLRDTR)) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+
+ currentDcb.fDtrControl = set ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE;
+ return true;
}
bool QSerialPortPrivate::setRequestToSend(bool set)
{
- return ::EscapeCommFunction(descriptor, set ? SETRTS : CLRRTS);
+ Q_Q(QSerialPort);
+
+ if (!::EscapeCommFunction(handle, set ? SETRTS : CLRRTS)) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+
+ return true;
}
#ifndef Q_OS_WINCE
bool QSerialPortPrivate::flush()
{
- return startAsyncWrite() && ::FlushFileBuffers(descriptor);
+ return startAsyncWrite() && ::FlushFileBuffers(handle);
}
bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
{
+ Q_Q(QSerialPort);
+
DWORD flags = 0;
if (directions & QSerialPort::Input)
flags |= PURGE_RXABORT | PURGE_RXCLEAR;
if (directions & QSerialPort::Output) {
flags |= PURGE_TXABORT | PURGE_TXCLEAR;
- writeSequenceStarted = false;
+ writeStarted = false;
+ }
+ if (!::PurgeComm(handle, flags)) {
+ q->setError(decodeSystemError());
+ return false;
}
- return ::PurgeComm(descriptor, flags);
+
+ return true;
}
#endif
bool QSerialPortPrivate::sendBreak(int duration)
{
- // FIXME:
- if (setBreakEnabled(true)) {
- ::Sleep(duration);
- if (setBreakEnabled(false))
- return true;
- }
- return false;
-}
+ if (!setBreakEnabled(true))
+ return false;
-bool QSerialPortPrivate::setBreakEnabled(bool set)
-{
- if (set)
- return ::SetCommBreak(descriptor);
- return ::ClearCommBreak(descriptor);
-}
+ ::Sleep(duration);
-qint64 QSerialPortPrivate::systemInputQueueSize ()
-{
- Q_Q(QSerialPort);
+ if (!setBreakEnabled(false))
+ return false;
- COMSTAT cs;
- ::ZeroMemory(&cs, sizeof(cs));
- if (!::ClearCommError(descriptor, NULL, &cs)) {
- q->setError(decodeSystemError());
- return -1;
- }
- return cs.cbInQue;
+ return true;
}
-qint64 QSerialPortPrivate::systemOutputQueueSize ()
+bool QSerialPortPrivate::setBreakEnabled(bool set)
{
Q_Q(QSerialPort);
- COMSTAT cs;
- ::ZeroMemory(&cs, sizeof(cs));
- if (!::ClearCommError(descriptor, NULL, &cs)) {
+ if (set ? !::SetCommBreak(handle) : !::ClearCommBreak(handle)) {
q->setError(decodeSystemError());
- return -1;
+ return false;
}
- return cs.cbOutQue;
+
+ return true;
}
#ifndef Q_OS_WINCE
-qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize)
+void QSerialPortPrivate::startWriting()
{
- char *ptr = writeBuffer.reserve(maxSize);
- if (maxSize == 1)
- *ptr = *data;
- else
- ::memcpy(ptr, data, maxSize);
-
- if (!writeSequenceStarted)
+ if (!writeStarted)
startAsyncWrite();
-
- return maxSize;
}
bool QSerialPortPrivate::waitForReadyRead(int msecs)
@@ -396,15 +392,15 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs)
}
if (triggeredEvent == communicationOverlapped.hEvent) {
- _q_canCompleteCommunication();
+ _q_completeAsyncCommunication();
} else if (triggeredEvent == readCompletionOverlapped.hEvent) {
- _q_canCompleteRead();
+ _q_completeAsyncRead();
if (qint64(readBuffer.size()) != currentReadBufferSize)
currentReadBufferSize = readBuffer.size();
else if (initialReadBufferSize != currentReadBufferSize)
return true;
} else if (triggeredEvent == writeCompletionOverlapped.hEvent) {
- _q_canCompleteWrite();
+ _q_completeAsyncWrite();
} else {
return false;
}
@@ -435,11 +431,11 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs)
}
if (triggeredEvent == communicationOverlapped.hEvent) {
- _q_canCompleteRead();
+ _q_completeAsyncRead();
} else if (triggeredEvent == readCompletionOverlapped.hEvent) {
- _q_canCompleteRead();
+ _q_completeAsyncRead();
} else if (triggeredEvent == writeCompletionOverlapped.hEvent) {
- _q_canCompleteWrite();
+ _q_completeAsyncWrite();
return error == QSerialPort::NoError;
} else {
return false;
@@ -548,13 +544,13 @@ bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy)
#ifndef Q_OS_WINCE
-void QSerialPortPrivate::_q_canCompleteCommunication()
+void QSerialPortPrivate::_q_completeAsyncCommunication()
{
Q_Q(QSerialPort);
DWORD numberOfBytesTransferred = 0;
- if (!::GetOverlappedResult(descriptor, &communicationOverlapped, &numberOfBytesTransferred, FALSE))
+ if (!::GetOverlappedResult(handle, &communicationOverlapped, &numberOfBytesTransferred, FALSE))
q->setError(decodeSystemError());
bool error = false;
@@ -580,41 +576,61 @@ void QSerialPortPrivate::_q_canCompleteCommunication()
startAsyncRead();
}
-void QSerialPortPrivate::_q_canCompleteRead()
+void QSerialPortPrivate::_q_completeAsyncRead()
{
Q_Q(QSerialPort);
DWORD numberOfBytesTransferred = 0;
- if (!::GetOverlappedResult(descriptor, &readCompletionOverlapped, &numberOfBytesTransferred, FALSE))
+ if (!::GetOverlappedResult(handle, &readCompletionOverlapped, &numberOfBytesTransferred, FALSE))
q->setError(decodeSystemError());
- completeAsyncRead(numberOfBytesTransferred);
+ if (numberOfBytesTransferred > 0) {
+
+ readBuffer.append(readChunkBuffer.left(numberOfBytesTransferred));
+
+ if (!emulateErrorPolicy())
+ emitReadyRead();
+ }
// start async read for possible remainder into driver queue
- if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy)) {
+ if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy))
startAsyncRead();
- } else { // driver queue is emplty, so startup wait comm event
- initializeOverlappedStructure(communicationOverlapped);
- if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) {
- const QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- q->setError(decodeSystemError());
- }
- }
- }
+ else // driver queue is emplty, so startup wait comm event
+ startAsyncCommunication();
}
-void QSerialPortPrivate::_q_canCompleteWrite()
+void QSerialPortPrivate::_q_completeAsyncWrite()
{
Q_Q(QSerialPort);
DWORD numberOfBytesTransferred = 0;
- if (!::GetOverlappedResult(descriptor, &writeCompletionOverlapped, &numberOfBytesTransferred, FALSE)) {
+ if (!::GetOverlappedResult(handle, &writeCompletionOverlapped, &numberOfBytesTransferred, FALSE)) {
numberOfBytesTransferred = 0;
q->setError(decodeSystemError());
}
- completeAsyncWrite(numberOfBytesTransferred);
+ if (numberOfBytesTransferred > 0) {
+ writeBuffer.free(numberOfBytesTransferred);
+ emit q->bytesWritten(numberOfBytesTransferred);
+ }
+
+ writeStarted = false;
+ startAsyncWrite();
+}
+
+bool QSerialPortPrivate::startAsyncCommunication()
+{
+ Q_Q(QSerialPort);
+
+ initializeOverlappedStructure(communicationOverlapped);
+ if (!::WaitCommEvent(handle, &triggeredEventMask, &communicationOverlapped)) {
+ const QSerialPort::SerialPortError error = decodeSystemError();
+ if (error != QSerialPort::NoError) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+ }
+ return true;
}
bool QSerialPortPrivate::startAsyncRead()
@@ -633,7 +649,7 @@ bool QSerialPortPrivate::startAsyncRead()
}
initializeOverlappedStructure(readCompletionOverlapped);
- if (::ReadFile(descriptor, readChunkBuffer.data(), bytesToRead, NULL, &readCompletionOverlapped))
+ if (::ReadFile(handle, readChunkBuffer.data(), bytesToRead, NULL, &readCompletionOverlapped))
return true;
QSerialPort::SerialPortError error = decodeSystemError();
@@ -652,33 +668,63 @@ bool QSerialPortPrivate::startAsyncWrite()
{
Q_Q(QSerialPort);
- qint64 nextSize = writeBuffer.nextDataBlockSize();
- const char *ptr = writeBuffer.readPointer();
-
- // no more data to write
- if (!ptr || nextSize == 0)
+ if (writeBuffer.isEmpty() || writeStarted)
return true;
- writeSequenceStarted = true;
-
initializeOverlappedStructure(writeCompletionOverlapped);
- if (::WriteFile(descriptor, ptr, nextSize, NULL, &writeCompletionOverlapped))
- return true;
+ if (!::WriteFile(handle, writeBuffer.readPointer(),
+ writeBuffer.nextDataBlockSize(),
+ NULL, &writeCompletionOverlapped)) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- writeSequenceStarted = false;
+ QSerialPort::SerialPortError error = decodeSystemError();
+ if (error != QSerialPort::NoError) {
+ if (error != QSerialPort::ResourceError)
+ error = QSerialPort::WriteError;
+ q->setError(error);
+ return false;
+ }
+ }
+
+ writeStarted = true;
+ return true;
+}
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::WriteError;
+bool QSerialPortPrivate::emulateErrorPolicy()
+{
+ if (!parityErrorOccurred)
+ return false;
- q->setError(error);
- return false;
+ parityErrorOccurred = false;
+
+ switch (policy) {
+ case QSerialPort::SkipPolicy:
+ readBuffer.getChar();
+ break;
+ case QSerialPort::PassZeroPolicy:
+ readBuffer.getChar();
+ readBuffer.putChar('\0');
+ emitReadyRead();
+ break;
+ case QSerialPort::IgnorePolicy:
+ return false;
+ case QSerialPort::StopReceivingPolicy:
+ emitReadyRead();
+ break;
+ default:
+ return false;
}
return true;
}
+void QSerialPortPrivate::emitReadyRead()
+{
+ Q_Q(QSerialPort);
+
+ readyReadEmitted = true;
+ emit q->readyRead();
+}
+
#endif // #ifndef Q_OS_WINCE
void QSerialPortPrivate::processIoErrors(bool error)
@@ -691,7 +737,7 @@ void QSerialPortPrivate::processIoErrors(bool error)
}
DWORD errors = 0;
- if (!::ClearCommError(descriptor, &errors, NULL)) {
+ if (!::ClearCommError(handle, &errors, NULL)) {
q->setError(decodeSystemError());
return;
}
@@ -710,66 +756,11 @@ void QSerialPortPrivate::processIoErrors(bool error)
#ifndef Q_OS_WINCE
-void QSerialPortPrivate::completeAsyncRead(DWORD numberOfBytes)
-{
- Q_Q(QSerialPort);
-
- if (numberOfBytes > 0) {
-
- readBuffer.append(readChunkBuffer.left(numberOfBytes));
-
- // Process emulate policy.
- if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) {
-
- parityErrorOccurred = false;
-
- // Ignore received character, remove it from buffer
- if (policy == QSerialPort::SkipPolicy) {
- readBuffer.getChar();
- // Force returning without emitting a readyRead() signal
- return;
- }
-
- // Abort receiving
- if (policy == QSerialPort::StopReceivingPolicy) {
- readyReadEmitted = true;
- emit q->readyRead();
- return;
- }
-
- // Replace received character by zero
- if (policy == QSerialPort::PassZeroPolicy) {
- readBuffer.getChar();
- readBuffer.putChar('\0');
- }
-
- }
-
- readyReadEmitted = true;
- emit q->readyRead();
- }
-}
-
-void QSerialPortPrivate::completeAsyncWrite(DWORD numberOfBytes)
-{
- Q_Q(QSerialPort);
-
- writeBuffer.free(numberOfBytes);
-
- if (numberOfBytes > 0)
- emit q->bytesWritten(numberOfBytes);
-
- if (writeBuffer.isEmpty())
- writeSequenceStarted = false;
- else
- startAsyncWrite();
-}
-
bool QSerialPortPrivate::updateDcb()
{
Q_Q(QSerialPort);
- if (!::SetCommState(descriptor, &currentDcb)) {
+ if (!::SetCommState(handle, &currentDcb)) {
q->setError(decodeSystemError());
return false;
}
@@ -780,7 +771,7 @@ bool QSerialPortPrivate::updateCommTimeouts()
{
Q_Q(QSerialPort);
- if (!::SetCommTimeouts(descriptor, &currentCommTimeouts)) {
+ if (!::SetCommTimeouts(handle, &currentCommTimeouts)) {
q->setError(decodeSystemError());
return false;
}
@@ -877,6 +868,9 @@ QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError() const
case ERROR_FILE_NOT_FOUND:
error = QSerialPort::DeviceNotFoundError;
break;
+ case ERROR_INVALID_NAME:
+ error = QSerialPort::DeviceNotFoundError;
+ break;
case ERROR_ACCESS_DENIED:
error = QSerialPort::PermissionError;
break;
@@ -1047,7 +1041,7 @@ QList<qint32> QSerialPortPrivate::standardBaudRates()
QSerialPort::Handle QSerialPort::handle() const
{
Q_D(const QSerialPort);
- return d->descriptor;
+ return d->handle;
}
QT_END_NAMESPACE
diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h
index 61e6ce80..ad5f267c 100644
--- a/src/serialport/qserialport_win_p.h
+++ b/src/serialport/qserialport_win_p.h
@@ -78,10 +78,7 @@ public:
bool sendBreak(int duration);
bool setBreakEnabled(bool set);
- qint64 systemInputQueueSize ();
- qint64 systemOutputQueueSize ();
-
- qint64 writeToBuffer(const char *data, qint64 maxSize);
+ void startWriting();
bool waitForReadyRead(int msec);
bool waitForBytesWritten(int msec);
@@ -96,14 +93,16 @@ public:
void processIoErrors(bool error);
QSerialPort::SerialPortError decodeSystemError() const;
#ifndef Q_OS_WINCE
- void _q_canCompleteCommunication();
- void _q_canCompleteRead();
- void _q_canCompleteWrite();
+ void _q_completeAsyncCommunication();
+ void _q_completeAsyncRead();
+ void _q_completeAsyncWrite();
+ bool startAsyncCommunication();
bool startAsyncRead();
bool startAsyncWrite();
- void completeAsyncRead(DWORD numberOfBytes);
- void completeAsyncWrite(DWORD numberOfBytes);
+
+ bool emulateErrorPolicy();
+ void emitReadyRead();
#else
bool notifyRead();
bool notifyWrite();
@@ -121,13 +120,13 @@ public:
DCB restoredDcb;
COMMTIMEOUTS currentCommTimeouts;
COMMTIMEOUTS restoredCommTimeouts;
- HANDLE descriptor;
+ HANDLE handle;
bool parityErrorOccurred;
#ifndef Q_OS_WINCE
QByteArray readChunkBuffer;
bool readyReadEmitted;
- bool writeSequenceStarted;
+ bool writeStarted;
QWinEventNotifier *communicationNotifier;
QWinEventNotifier *readCompletionNotifier;
QWinEventNotifier *writeCompletionNotifier;
diff --git a/src/serialport/qserialport_wince.cpp b/src/serialport/qserialport_wince.cpp
index 26ebf64c..b987c802 100644
--- a/src/serialport/qserialport_wince.cpp
+++ b/src/serialport/qserialport_wince.cpp
@@ -62,12 +62,12 @@ public:
CommEventNotifier(DWORD mask, QSerialPortPrivate *d, QObject *parent)
: QThread(parent), dptr(d), running(true) {
connect(this, SIGNAL(eventMask(quint32)), this, SLOT(processNotification(quint32)));
- ::SetCommMask(dptr->descriptor, mask);
+ ::SetCommMask(dptr->handle, mask);
}
virtual ~CommEventNotifier() {
running = false;
- ::SetCommMask(dptr->descriptor, 0);
+ ::SetCommMask(dptr->handle, 0);
wait();
}
@@ -75,7 +75,7 @@ protected:
void run() Q_DECL_OVERRIDE {
DWORD mask = 0;
while (running) {
- if (::WaitCommEvent(dptr->descriptor, &mask, FALSE)) {
+ if (::WaitCommEvent(dptr->handle, &mask, FALSE)) {
// Wait until complete the operation changes the port settings,
// see updateDcb().
dptr->settingsChangeMutex.lock();
@@ -115,8 +115,8 @@ class WaitCommEventBreaker : public QThread
{
Q_OBJECT
public:
- WaitCommEventBreaker(HANDLE descriptor, int timeout, QObject *parent = 0)
- : QThread(parent), descriptor(descriptor), timeout(timeout), worked(false) {
+ WaitCommEventBreaker(HANDLE handle, int timeout, QObject *parent = 0)
+ : QThread(parent), handle(handle), timeout(timeout), worked(false) {
start();
}
@@ -144,12 +144,12 @@ protected:
private slots:
void processTimeout() {
- ::SetCommMask(descriptor, 0);
+ ::SetCommMask(handle, 0);
stop();
}
private:
- HANDLE descriptor;
+ HANDLE handle;
int timeout;
mutable bool worked;
};
@@ -158,7 +158,7 @@ private:
QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
: QSerialPortPrivateData(q)
- , descriptor(INVALID_HANDLE_VALUE)
+ , handle(INVALID_HANDLE_VALUE)
, parityErrorOccurred(false)
, eventNotifier(0)
{
@@ -180,15 +180,18 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
eventMask |= EV_TXEMPTY;
}
- descriptor = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation.utf16()),
+ handle = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation.utf16()),
desiredAccess, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (descriptor == INVALID_HANDLE_VALUE) {
+ if (handle == INVALID_HANDLE_VALUE) {
q->setError(decodeSystemError());
return false;
}
- if (!::GetCommState(descriptor, &restoredDcb)) {
+ ::ZeroMemory(&restoredDcb, sizeof(restoredDcb));
+ restoredDcb.DCBlength = sizeof(restoredDcb);
+
+ if (!::GetCommState(handle, &restoredDcb)) {
q->setError(decodeSystemError());
return false;
}
@@ -201,10 +204,13 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
currentDcb.fNull = false;
currentDcb.fErrorChar = false;
+ if (currentDcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
+ currentDcb.fDtrControl = DTR_CONTROL_DISABLE;
+
if (!updateDcb())
return false;
- if (!::GetCommTimeouts(descriptor, &restoredCommTimeouts)) {
+ if (!::GetCommTimeouts(handle, &restoredCommTimeouts)) {
q->setError(decodeSystemError());
return false;
}
@@ -230,17 +236,17 @@ void QSerialPortPrivate::close()
}
if (settingsRestoredOnClose) {
- ::SetCommState(descriptor, &restoredDcb);
- ::SetCommTimeouts(descriptor, &restoredCommTimeouts);
+ ::SetCommState(handle, &restoredDcb);
+ ::SetCommTimeouts(handle, &restoredCommTimeouts);
}
- ::CloseHandle(descriptor);
- descriptor = INVALID_HANDLE_VALUE;
+ ::CloseHandle(handle);
+ handle = INVALID_HANDLE_VALUE;
}
bool QSerialPortPrivate::flush()
{
- return notifyWrite() && ::FlushFileBuffers(descriptor);
+ return notifyWrite() && ::FlushFileBuffers(handle);
}
bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
@@ -250,21 +256,13 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
flags |= PURGE_RXABORT | PURGE_RXCLEAR;
if (directions & QSerialPort::Output)
flags |= PURGE_TXABORT | PURGE_TXCLEAR;
- return ::PurgeComm(descriptor, flags);
+ return ::PurgeComm(handle, flags);
}
-qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize)
+void QSerialPortPrivate::startWriting()
{
- char *ptr = writeBuffer.reserve(maxSize);
- if (maxSize == 1)
- *ptr = *data;
- else
- ::memcpy(ptr, data, maxSize);
-
// trigger write sequence
notifyWrite();
-
- return maxSize;
}
bool QSerialPortPrivate::waitForReadyRead(int msec)
@@ -345,7 +343,7 @@ bool QSerialPortPrivate::notifyRead()
char *ptr = readBuffer.reserve(bytesToRead);
DWORD readBytes = 0;
- BOOL sucessResult = ::ReadFile(descriptor, ptr, bytesToRead, &readBytes, NULL);
+ BOOL sucessResult = ::ReadFile(handle, ptr, bytesToRead, &readBytes, NULL);
if (!sucessResult) {
readBuffer.truncate(bytesToRead);
@@ -391,7 +389,7 @@ bool QSerialPortPrivate::notifyWrite()
const char *ptr = writeBuffer.readPointer();
DWORD bytesWritten = 0;
- if (!::WriteFile(descriptor, ptr, nextSize, &bytesWritten, NULL)) {
+ if (!::WriteFile(handle, ptr, nextSize, &bytesWritten, NULL)) {
q->setError(QSerialPort::WriteError);
return false;
}
@@ -414,8 +412,8 @@ bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectFor
// FIXME: Here the situation is not properly handled with zero timeout:
// breaker can work out before you call a method WaitCommEvent()
// and so it will loop forever!
- WaitCommEventBreaker breaker(descriptor, qMax(msecs, 0));
- ::WaitCommEvent(descriptor, &eventMask, NULL);
+ WaitCommEventBreaker breaker(handle, qMax(msecs, 0));
+ ::WaitCommEvent(handle, &eventMask, NULL);
breaker.stop();
if (breaker.isWorked()) {
@@ -447,17 +445,17 @@ bool QSerialPortPrivate::updateDcb()
DWORD eventMask = 0;
// Save the event mask
- if (!::GetCommMask(descriptor, &eventMask))
+ if (!::GetCommMask(handle, &eventMask))
return false;
// Break event notifier from WaitCommEvent
- ::SetCommMask(descriptor, 0);
+ ::SetCommMask(handle, 0);
// Change parameters
- bool ret = ::SetCommState(descriptor, &currentDcb);
+ bool ret = ::SetCommState(handle, &currentDcb);
if (!ret)
q->setError(decodeSystemError());
// Restore the event mask
- ::SetCommMask(descriptor, eventMask);
+ ::SetCommMask(handle, eventMask);
return ret;
}
@@ -466,7 +464,7 @@ bool QSerialPortPrivate::updateCommTimeouts()
{
Q_Q(QSerialPort);
- if (!::SetCommTimeouts(descriptor, &currentCommTimeouts)) {
+ if (!::SetCommTimeouts(handle, &currentCommTimeouts)) {
q->setError(decodeSystemError());
return false;
}
diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp
index 4433a4e4..80b2f7d8 100644
--- a/src/serialport/qserialportinfo_unix.cpp
+++ b/src/serialport/qserialportinfo_unix.cpp
@@ -115,81 +115,81 @@ QList<QSerialPortInfo> availablePortsByFiltersOfDevices()
QList<QSerialPortInfo> availablePortsBySysfs()
{
- QList<QSerialPortInfo> serialPortInfoList;
QDir ttySysClassDir(QStringLiteral("/sys/class/tty"));
- const bool sysfsEnabled = ttySysClassDir.exists() && ttySysClassDir.isReadable();
- if (sysfsEnabled) {
- ttySysClassDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
- foreach (const QFileInfo &fileInfo, ttySysClassDir.entryInfoList()) {
- if (!fileInfo.isSymLink())
- continue;
+ if (!(ttySysClassDir.exists() && ttySysClassDir.isReadable()))
+ return QList<QSerialPortInfo>();
- const QString targetPath = fileInfo.symLinkTarget();
- const int lastIndexOfSlash = targetPath.lastIndexOf(QLatin1Char('/'));
- if (lastIndexOfSlash == -1)
- continue;
+ QList<QSerialPortInfo> serialPortInfoList;
+ ttySysClassDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
+ foreach (const QFileInfo &fileInfo, ttySysClassDir.entryInfoList()) {
+ if (!fileInfo.isSymLink())
+ continue;
- QSerialPortInfo serialPortInfo;
+ const QString targetPath = fileInfo.symLinkTarget();
+ const int lastIndexOfSlash = targetPath.lastIndexOf(QLatin1Char('/'));
+ if (lastIndexOfSlash == -1)
+ continue;
- if (targetPath.contains(QStringLiteral("pnp"))) {
- // TODO: Obtain more information
- } else if (targetPath.contains(QStringLiteral("platform"))) {
- continue;
- } else if (targetPath.contains(QStringLiteral("usb"))) {
+ QSerialPortInfo serialPortInfo;
- QDir targetDir(targetPath);
- targetDir.setFilter(QDir::Files | QDir::Readable);
- targetDir.setNameFilters(QStringList(QStringLiteral("uevent")));
+ if (targetPath.contains(QStringLiteral("pnp"))) {
+ // TODO: Obtain more information
+ } else if (targetPath.contains(QStringLiteral("platform"))) {
+ continue;
+ } else if (targetPath.contains(QStringLiteral("usb"))) {
- do {
- const QFileInfoList entryInfoList = targetDir.entryInfoList();
- if (entryInfoList.isEmpty())
- continue;
+ QDir targetDir(targetPath);
+ targetDir.setFilter(QDir::Files | QDir::Readable);
+ targetDir.setNameFilters(QStringList(QStringLiteral("uevent")));
- QFile uevent(entryInfoList.first().absoluteFilePath());
- if (!uevent.open(QIODevice::ReadOnly | QIODevice::Text))
- continue;
+ do {
+ const QFileInfoList entryInfoList = targetDir.entryInfoList();
+ if (entryInfoList.isEmpty())
+ continue;
- const QString ueventContent = QString::fromLatin1(uevent.readAll());
+ QFile uevent(entryInfoList.first().absoluteFilePath());
+ if (!uevent.open(QIODevice::ReadOnly | QIODevice::Text))
+ continue;
- if (ueventContent.contains(QStringLiteral("DEVTYPE=usb_device"))
- && ueventContent.contains(QStringLiteral("DRIVER=usb"))) {
+ const QString ueventContent = QString::fromLatin1(uevent.readAll());
- QFile description(QFileInfo(targetDir, QStringLiteral("product")).absoluteFilePath());
- if (description.open(QIODevice::ReadOnly | QIODevice::Text))
- serialPortInfo.d_ptr->description = QString::fromLatin1(description.readAll()).simplified();
+ if (ueventContent.contains(QStringLiteral("DEVTYPE=usb_device"))
+ && ueventContent.contains(QStringLiteral("DRIVER=usb"))) {
- QFile manufacturer(QFileInfo(targetDir, QStringLiteral("manufacturer")).absoluteFilePath());
- if (manufacturer.open(QIODevice::ReadOnly | QIODevice::Text))
- serialPortInfo.d_ptr->manufacturer = QString::fromLatin1(manufacturer.readAll()).simplified();
+ QFile description(QFileInfo(targetDir, QStringLiteral("product")).absoluteFilePath());
+ if (description.open(QIODevice::ReadOnly | QIODevice::Text))
+ serialPortInfo.d_ptr->description = QString::fromLatin1(description.readAll()).simplified();
- QFile vendorIdentifier(QFileInfo(targetDir, QStringLiteral("idVendor")).absoluteFilePath());
- if (vendorIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
- serialPortInfo.d_ptr->vendorIdentifier = QString::fromLatin1(vendorIdentifier.readAll())
- .toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16);
- }
+ QFile manufacturer(QFileInfo(targetDir, QStringLiteral("manufacturer")).absoluteFilePath());
+ if (manufacturer.open(QIODevice::ReadOnly | QIODevice::Text))
+ serialPortInfo.d_ptr->manufacturer = QString::fromLatin1(manufacturer.readAll()).simplified();
- QFile productIdentifier(QFileInfo(targetDir, QStringLiteral("idProduct")).absoluteFilePath());
- if (productIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
- serialPortInfo.d_ptr->productIdentifier = QString::fromLatin1(productIdentifier.readAll())
- .toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16);
- }
+ QFile vendorIdentifier(QFileInfo(targetDir, QStringLiteral("idVendor")).absoluteFilePath());
+ if (vendorIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ serialPortInfo.d_ptr->vendorIdentifier = QString::fromLatin1(vendorIdentifier.readAll())
+ .toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16);
+ }
- break;
+ QFile productIdentifier(QFileInfo(targetDir, QStringLiteral("idProduct")).absoluteFilePath());
+ if (productIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ serialPortInfo.d_ptr->productIdentifier = QString::fromLatin1(productIdentifier.readAll())
+ .toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16);
}
- } while (targetDir.cdUp());
- } else if (targetPath.contains(QStringLiteral("pci"))) {
- // TODO: Obtain more information about the device
- } else {
- continue;
- }
+ break;
+ }
+ } while (targetDir.cdUp());
- serialPortInfo.d_ptr->portName = targetPath.mid(lastIndexOfSlash + 1);
- serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(serialPortInfo.d_ptr->portName);
- serialPortInfoList.append(serialPortInfo);
+ } else if (targetPath.contains(QStringLiteral("pci"))) {
+ // TODO: Obtain more information about the device
+ } else {
+ continue;
}
+
+ serialPortInfo.d_ptr->portName = targetPath.mid(lastIndexOfSlash + 1);
+ serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(serialPortInfo.d_ptr->portName);
+ serialPortInfoList.append(serialPortInfo);
}
return serialPortInfoList;
diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp
index 51f529e9..e6296a2d 100644
--- a/src/serialport/qserialportinfo_win.cpp
+++ b/src/serialport/qserialportinfo_win.cpp
@@ -75,6 +75,35 @@ static inline const QList<GuidFlagsPair>& guidFlagsPairs()
return guidFlagsPairList;
}
+static QStringList portNamesFromHardwareDeviceMap()
+{
+ HKEY hKey = 0;
+ if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+ return QStringList();
+
+ QStringList result;
+ DWORD index = 0;
+ static const DWORD maximumValueNameInChars = 16383;
+ QByteArray outputValueName(maximumValueNameInChars * sizeof(wchar_t), 0);
+ QByteArray outputBuffer;
+ DWORD requiredDataBytes = 0;
+ forever {
+ DWORD requiredValueNameChars = maximumValueNameInChars;
+ const LONG ret = ::RegEnumValue(hKey, index, reinterpret_cast<wchar_t *>(outputValueName.data()), &requiredValueNameChars,
+ NULL, NULL, reinterpret_cast<unsigned char *>(outputBuffer.data()), &requiredDataBytes);
+ if (ret == ERROR_MORE_DATA) {
+ outputBuffer.resize(requiredDataBytes);
+ } else if (ret == ERROR_SUCCESS) {
+ result.append(QString::fromWCharArray(reinterpret_cast<const wchar_t *>(outputBuffer.constData())));
+ ++index;
+ } else {
+ break;
+ }
+ }
+ ::RegCloseKey(hKey);
+ return result;
+}
+
static QVariant deviceRegistryProperty(HDEVINFO deviceInfoSet,
PSP_DEVINFO_DATA deviceInfoData,
DWORD property)
@@ -137,28 +166,37 @@ static QString deviceInstanceIdentifier(HDEVINFO deviceInfoSet,
static QString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData)
{
- static const wchar_t portKeyName[] = L"PortName";
-
const HKEY key = ::SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL,
0, DIREG_DEV, KEY_READ);
if (key == INVALID_HANDLE_VALUE)
return QString();
- DWORD dataSize;
- if (::RegQueryValueEx(key, portKeyName, NULL, NULL, NULL, &dataSize) != ERROR_SUCCESS) {
- ::RegCloseKey(key);
- return QString();
- }
+ static const QStringList portNameRegistryKeyList = QStringList()
+ << QStringLiteral("PortName")
+ << QStringLiteral("PortNumber");
- QByteArray data(dataSize, 0);
-
- if (::RegQueryValueEx(key, portKeyName, NULL, NULL,
- reinterpret_cast<unsigned char *>(data.data()), &dataSize) != ERROR_SUCCESS) {
- ::RegCloseKey(key);
- return QString();
+ QString portName;
+ foreach (const QString &portNameKey, portNameRegistryKeyList) {
+ DWORD bytesRequired = 0;
+ DWORD dataType = 0;
+ QByteArray outputBuffer;
+ forever {
+ const LONG ret = ::RegQueryValueEx(key, reinterpret_cast<const wchar_t *>(portNameKey.utf16()), NULL, &dataType,
+ reinterpret_cast<unsigned char *>(outputBuffer.data()), &bytesRequired);
+ if (ret == ERROR_MORE_DATA) {
+ outputBuffer.resize(bytesRequired);
+ continue;
+ } else if (ret == ERROR_SUCCESS) {
+ if (dataType == REG_SZ)
+ portName = QString::fromWCharArray((reinterpret_cast<const wchar_t *>(outputBuffer.constData())));
+ else if (dataType == REG_DWORD)
+ portName = QStringLiteral("COM%1").arg(*(PDWORD(outputBuffer.constData())));
+ }
+ break;
+ }
}
::RegCloseKey(key);
- return QString::fromWCharArray(((const wchar_t *)data.constData()));
+ return portName;
}
class SerialPortNameEqualFunctor
@@ -247,6 +285,17 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
}
::SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
+
+ foreach (const QString &portName, portNamesFromHardwareDeviceMap()) {
+ if (std::find_if(serialPortInfoList.begin(), serialPortInfoList.end(),
+ SerialPortNameEqualFunctor(portName)) == serialPortInfoList.end()) {
+ QSerialPortInfo serialPortInfo;
+ serialPortInfo.d_ptr->portName = portName;
+ serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(portName);
+ serialPortInfoList.append(serialPortInfo);
+ }
+ }
+
return serialPortInfoList;
}
@@ -259,28 +308,28 @@ QList<qint32> QSerialPortInfo::standardBaudRates()
bool QSerialPortInfo::isBusy() const
{
- const HANDLE descriptor = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation().utf16()),
+ const HANDLE handle = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation().utf16()),
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (descriptor == INVALID_HANDLE_VALUE) {
+ if (handle == INVALID_HANDLE_VALUE) {
if (::GetLastError() == ERROR_ACCESS_DENIED)
return true;
} else {
- ::CloseHandle(descriptor);
+ ::CloseHandle(handle);
}
return false;
}
bool QSerialPortInfo::isValid() const
{
- const HANDLE descriptor = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation().utf16()),
+ const HANDLE handle = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation().utf16()),
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (descriptor == INVALID_HANDLE_VALUE) {
+ if (handle == INVALID_HANDLE_VALUE) {
if (::GetLastError() != ERROR_ACCESS_DENIED)
return false;
} else {
- ::CloseHandle(descriptor);
+ ::CloseHandle(handle);
}
return true;
}