summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-14 14:07:32 +0200
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-14 14:07:32 +0200
commit3bb682ea29ffaf72ff73e6eb57abdc5c59524e8a (patch)
tree4d8e828da7ea6115c6ffe26cec2d024bad60aa91
parent14fe584d2abb1ae0776f0973b245baa79d0468d2 (diff)
parent62dfdeb3642250bdb642dbf607a8c7b95e57835e (diff)
downloadqtserialport-3bb682ea29ffaf72ff73e6eb57abdc5c59524e8a.tar.gz
Merge remote-tracking branch 'origin/5.3' into 5.4
Change-Id: Id7e66059233e8d07ba44cad19048d9cddc68e250
-rw-r--r--src/serialport/qserialport.cpp10
-rw-r--r--src/serialport/qserialport_unix.cpp28
-rw-r--r--src/serialport/qserialport_unix_p.h5
-rw-r--r--src/serialport/qserialport_win.cpp78
-rw-r--r--src/serialport/qserialport_win_p.h7
-rw-r--r--src/serialport/qserialport_wince.cpp18
-rw-r--r--src/serialport/qserialport_wince_p.h5
-rw-r--r--src/serialport/qserialportinfo_mac.cpp3
-rw-r--r--src/serialport/qserialportinfo_unix.cpp14
-rw-r--r--src/serialport/qserialportinfo_win.cpp6
-rw-r--r--src/serialport/qtudev_p.h2
-rw-r--r--tests/auto/qserialport/tst_qserialport.cpp91
12 files changed, 215 insertions, 52 deletions
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp
index 297bf62..82bcde3 100644
--- a/src/serialport/qserialport.cpp
+++ b/src/serialport/qserialport.cpp
@@ -1218,7 +1218,7 @@ qint64 QSerialPort::bytesAvailable() const
qint64 QSerialPort::bytesToWrite() const
{
Q_D(const QSerialPort);
- return d->writeBuffer.size() + QIODevice::bytesToWrite();
+ return d->bytesToWrite() + QIODevice::bytesToWrite();
}
/*!
@@ -1335,7 +1335,7 @@ bool QSerialPort::setBreakEnabled(bool set)
qint64 QSerialPort::readData(char *data, qint64 maxSize)
{
Q_D(QSerialPort);
- return d->readBuffer.read(data, maxSize);
+ return d->readData(data, maxSize);
}
/*!
@@ -1352,11 +1352,7 @@ qint64 QSerialPort::readLineData(char *data, qint64 maxSize)
qint64 QSerialPort::writeData(const char *data, qint64 maxSize)
{
Q_D(QSerialPort);
-
- ::memcpy(d->writeBuffer.reserve(maxSize), data, maxSize);
- if (!d->writeBuffer.isEmpty())
- d->startWriting();
- return maxSize;
+ return d->writeData(data, maxSize);
}
void QSerialPort::setError(QSerialPort::SerialPortError serialPortError, const QString &errorString)
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index afdc640..9979256 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -369,10 +369,9 @@ bool QSerialPortPrivate::setBreakEnabled(bool set)
return true;
}
-void QSerialPortPrivate::startWriting()
+qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
{
- if (!isWriteNotificationEnabled())
- setWriteNotificationEnabled(true);
+ return readBuffer.read(data, maxSize);
}
bool QSerialPortPrivate::waitForReadyRead(int msecs)
@@ -496,9 +495,6 @@ QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions d
if (::ioctl(descriptor, TIOCGSERIAL, &currentSerialInfo) == -1)
return decodeSystemError();
- if (currentSerialInfo.baud_base % baudRate != 0)
- return QSerialPort::UnsupportedOperationError;
-
currentSerialInfo.flags &= ~ASYNC_SPD_MASK;
currentSerialInfo.flags |= (ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/);
currentSerialInfo.custom_divisor = currentSerialInfo.baud_base / baudRate;
@@ -506,6 +502,13 @@ QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions d
if (currentSerialInfo.custom_divisor == 0)
return QSerialPort::UnsupportedOperationError;
+ if (currentSerialInfo.custom_divisor * baudRate != currentSerialInfo.baud_base) {
+ qWarning("Baud rate of serial port %s is set to %d instead of %d: divisor %f unsupported",
+ qPrintable(systemLocation),
+ currentSerialInfo.baud_base / currentSerialInfo.custom_divisor,
+ baudRate, (float)currentSerialInfo.baud_base / baudRate);
+ }
+
if (::ioctl(descriptor, TIOCSSERIAL, &currentSerialInfo) == -1)
return decodeSystemError();
@@ -868,6 +871,19 @@ inline bool QSerialPortPrivate::initialize(QIODevice::OpenMode mode)
return true;
}
+qint64 QSerialPortPrivate::bytesToWrite() const
+{
+ return writeBuffer.size();
+}
+
+qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
+{
+ ::memcpy(writeBuffer.reserve(maxSize), data, maxSize);
+ if (!writeBuffer.isEmpty() && !isWriteNotificationEnabled())
+ setWriteNotificationEnabled(true);
+ return maxSize;
+}
+
bool QSerialPortPrivate::updateTermios()
{
Q_Q(QSerialPort);
diff --git a/src/serialport/qserialport_unix_p.h b/src/serialport/qserialport_unix_p.h
index e24804d..1cc767d 100644
--- a/src/serialport/qserialport_unix_p.h
+++ b/src/serialport/qserialport_unix_p.h
@@ -111,7 +111,7 @@ public:
bool sendBreak(int duration);
bool setBreakEnabled(bool set);
- void startWriting();
+ qint64 readData(char *data, qint64 maxSize);
bool waitForReadyRead(int msecs);
bool waitForBytesWritten(int msecs);
@@ -128,6 +128,9 @@ public:
bool startAsyncWrite();
bool completeAsyncWrite();
+ qint64 bytesToWrite() const;
+ qint64 writeData(const char *data, qint64 maxSize);
+
static QString portNameToSystemLocation(const QString &port);
static QString portNameFromSystemLocation(const QString &location);
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index 32b8d0a..64ca00e 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -90,12 +90,14 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
, readChunkBuffer(ReadChunkSize, 0)
, readyReadEmitted(0)
, writeStarted(false)
+ , readStarted(false)
, communicationNotifier(new QWinEventNotifier(q))
, readCompletionNotifier(new QWinEventNotifier(q))
, writeCompletionNotifier(new QWinEventNotifier(q))
, startAsyncWriteTimer(0)
, originalEventMask(0)
, triggeredEventMask(0)
+ , actualBytesToWrite(0)
{
::ZeroMemory(&communicationOverlapped, sizeof(communicationOverlapped));
communicationOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -165,10 +167,12 @@ void QSerialPortPrivate::close()
writeCompletionNotifier->setEnabled(false);
communicationNotifier->setEnabled(false);
+ readStarted = false;
readBuffer.clear();
writeStarted = false;
writeBuffer.clear();
+ actualBytesToWrite = 0;
readyReadEmitted = false;
parityErrorOccurred = false;
@@ -259,17 +263,26 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
Q_Q(QSerialPort);
DWORD flags = 0;
- if (directions & QSerialPort::Input)
+ if (directions & QSerialPort::Input) {
flags |= PURGE_RXABORT | PURGE_RXCLEAR;
+ readStarted = false;
+ }
if (directions & QSerialPort::Output) {
flags |= PURGE_TXABORT | PURGE_TXCLEAR;
writeStarted = false;
+ actualBytesToWrite = 0;
}
if (!::PurgeComm(handle, flags)) {
q->setError(decodeSystemError());
return false;
}
+ // We need start async read because a reading can be stalled. Since the
+ // PurgeComm can abort of current reading sequence, or a port is in hardware
+ // flow control mode, or a port has a limited read buffer size.
+ if (directions & QSerialPort::Input)
+ startAsyncRead();
+
return true;
}
@@ -298,18 +311,19 @@ bool QSerialPortPrivate::setBreakEnabled(bool set)
return true;
}
-void QSerialPortPrivate::startWriting()
+qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
{
- Q_Q(QSerialPort);
-
- if (!writeStarted) {
- if (!startAsyncWriteTimer) {
- startAsyncWriteTimer = new QTimer(q);
- q->connect(startAsyncWriteTimer, SIGNAL(timeout()), q, SLOT(_q_startAsyncWrite()));
- startAsyncWriteTimer->setSingleShot(true);
- }
- startAsyncWriteTimer->start(0);
+ const qint64 result = readBuffer.read(data, maxSize);
+ // We need try to start async reading to read a remainder from a driver's queue
+ // in case we have a limited read buffer size. Because the read notification can
+ // be stalled since Windows do not re-triggered an EV_RXCHAR event if a driver's
+ // buffer has a remainder of data ready to read until a new data will be received.
+ if (readBufferMaxSize
+ && result > 0
+ && (result == readBufferMaxSize || flowControl == QSerialPort::HardwareControl)) {
+ startAsyncRead();
}
+ return result;
}
bool QSerialPortPrivate::waitForReadyRead(int msecs)
@@ -515,14 +529,18 @@ bool QSerialPortPrivate::_q_completeAsyncCommunication()
bool QSerialPortPrivate::_q_completeAsyncRead()
{
const qint64 bytesTransferred = handleOverlappedResult(QSerialPort::Input, readCompletionOverlapped);
- if (bytesTransferred == qint64(-1))
+ if (bytesTransferred == qint64(-1)) {
+ readStarted = false;
return false;
+ }
if (bytesTransferred > 0) {
readBuffer.append(readChunkBuffer.left(bytesTransferred));
if (!emulateErrorPolicy())
emitReadyRead();
}
+ readStarted = false;
+
// start async read for possible remainder into driver queue
if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
return startAsyncRead();
@@ -570,6 +588,9 @@ bool QSerialPortPrivate::startAsyncRead()
{
Q_Q(QSerialPort);
+ if (readStarted)
+ return true;
+
DWORD bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1;
if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) {
@@ -582,8 +603,10 @@ bool QSerialPortPrivate::startAsyncRead()
}
initializeOverlappedStructure(readCompletionOverlapped);
- if (::ReadFile(handle, readChunkBuffer.data(), bytesToRead, NULL, &readCompletionOverlapped))
+ if (::ReadFile(handle, readChunkBuffer.data(), bytesToRead, NULL, &readCompletionOverlapped)) {
+ readStarted = true;
return true;
+ }
QSerialPort::SerialPortError error = decodeSystemError();
if (error != QSerialPort::NoError) {
@@ -595,6 +618,7 @@ bool QSerialPortPrivate::startAsyncRead()
return false;
}
+ readStarted = true;
return true;
}
@@ -606,8 +630,10 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
return true;
initializeOverlappedStructure(writeCompletionOverlapped);
+
+ const int writeBytes = writeBuffer.nextDataBlockSize();
if (!::WriteFile(handle, writeBuffer.readPointer(),
- writeBuffer.nextDataBlockSize(),
+ writeBytes,
NULL, &writeCompletionOverlapped)) {
QSerialPort::SerialPortError error = decodeSystemError();
@@ -619,6 +645,7 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
}
}
+ actualBytesToWrite -= writeBytes;
writeStarted = true;
return true;
}
@@ -659,6 +686,29 @@ void QSerialPortPrivate::emitReadyRead()
emit q->readyRead();
}
+qint64 QSerialPortPrivate::bytesToWrite() const
+{
+ return actualBytesToWrite;
+}
+
+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) {
+ startAsyncWriteTimer = new QTimer(q);
+ q->connect(startAsyncWriteTimer, SIGNAL(timeout()), q, SLOT(_q_completeAsyncWrite()));
+ startAsyncWriteTimer->setSingleShot(true);
+ }
+ startAsyncWriteTimer->start(0);
+ }
+ return maxSize;
+}
+
void QSerialPortPrivate::handleLineStatusErrors()
{
Q_Q(QSerialPort);
diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h
index 93f8591..6b009fe 100644
--- a/src/serialport/qserialport_win_p.h
+++ b/src/serialport/qserialport_win_p.h
@@ -78,7 +78,7 @@ public:
bool sendBreak(int duration);
bool setBreakEnabled(bool set);
- void startWriting();
+ qint64 readData(char *data, qint64 maxSize);
bool waitForReadyRead(int msec);
bool waitForBytesWritten(int msec);
@@ -105,6 +105,9 @@ public:
bool emulateErrorPolicy();
void emitReadyRead();
+ qint64 bytesToWrite() const;
+ qint64 writeData(const char *data, qint64 maxSize);
+
static QString portNameToSystemLocation(const QString &port);
static QString portNameFromSystemLocation(const QString &location);
@@ -122,6 +125,7 @@ public:
QByteArray readChunkBuffer;
bool readyReadEmitted;
bool writeStarted;
+ bool readStarted;
QWinEventNotifier *communicationNotifier;
QWinEventNotifier *readCompletionNotifier;
QWinEventNotifier *writeCompletionNotifier;
@@ -131,6 +135,7 @@ public:
OVERLAPPED writeCompletionOverlapped;
DWORD originalEventMask;
DWORD triggeredEventMask;
+ qint64 actualBytesToWrite;
private:
bool initialize(QIODevice::OpenMode mode);
diff --git a/src/serialport/qserialport_wince.cpp b/src/serialport/qserialport_wince.cpp
index 1cf79cc..a9c80b2 100644
--- a/src/serialport/qserialport_wince.cpp
+++ b/src/serialport/qserialport_wince.cpp
@@ -337,10 +337,9 @@ bool QSerialPortPrivate::setBreakEnabled(bool set)
return true;
}
-void QSerialPortPrivate::startWriting()
+qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
{
- // trigger write sequence
- notifyWrite();
+ return readBuffer.read(data, maxSize);
}
bool QSerialPortPrivate::waitForReadyRead(int msec)
@@ -579,6 +578,19 @@ bool QSerialPortPrivate::notifyWrite()
return true;
}
+qint64 QSerialPortPrivate::bytesToWrite() const
+{
+ return writeBuffer.size();
+}
+
+qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
+{
+ ::memcpy(writeBuffer.reserve(maxSize), data, maxSize);
+ if (!writeBuffer.isEmpty())
+ notifyWrite();
+ return maxSize;
+}
+
void QSerialPortPrivate::processIoErrors(bool error)
{
Q_Q(QSerialPort);
diff --git a/src/serialport/qserialport_wince_p.h b/src/serialport/qserialport_wince_p.h
index 164a87e..dedd4b1 100644
--- a/src/serialport/qserialport_wince_p.h
+++ b/src/serialport/qserialport_wince_p.h
@@ -77,7 +77,7 @@ public:
bool sendBreak(int duration);
bool setBreakEnabled(bool set);
- void startWriting();
+ qint64 readData(char *data, qint64 maxSize);
bool waitForReadyRead(int msec);
bool waitForBytesWritten(int msec);
@@ -96,6 +96,9 @@ public:
bool notifyRead();
bool notifyWrite();
+ qint64 bytesToWrite() const;
+ qint64 writeData(const char *data, qint64 maxSize);
+
static QString portNameToSystemLocation(const QString &port);
static QString portNameFromSystemLocation(const QString &location);
diff --git a/src/serialport/qserialportinfo_mac.cpp b/src/serialport/qserialportinfo_mac.cpp
index e307136..d400d68 100644
--- a/src/serialport/qserialportinfo_mac.cpp
+++ b/src/serialport/qserialportinfo_mac.cpp
@@ -64,8 +64,7 @@ static QCFType<CFTypeRef> searchProperty(io_registry_entry_t ioRegistryEntry,
static QString searchStringProperty(io_registry_entry_t ioRegistryEntry,
const QCFString &propertyKey)
{
- const QCFString result(searchProperty(ioRegistryEntry, propertyKey).as<CFStringRef>());
- return QCFString::toQString(result);
+ return QCFString::toQString(searchProperty(ioRegistryEntry, propertyKey).as<CFStringRef>());
}
static quint16 searchShortIntProperty(io_registry_entry_t ioRegistryEntry,
diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp
index 82ac91f..4479e97 100644
--- a/src/serialport/qserialportinfo_unix.cpp
+++ b/src/serialport/qserialportinfo_unix.cpp
@@ -161,6 +161,10 @@ QList<QSerialPortInfo> availablePortsBySysfs()
if (manufacturer.open(QIODevice::ReadOnly | QIODevice::Text))
serialPortInfo.d_ptr->manufacturer = QString::fromLatin1(manufacturer.readAll()).simplified();
+ QFile serialNumber(QFileInfo(targetDir, QStringLiteral("serial")).absoluteFilePath());
+ if (serialNumber.open(QIODevice::ReadOnly | QIODevice::Text))
+ serialPortInfo.d_ptr->serialNumber = QString::fromLatin1(serialNumber.readAll()).simplified();
+
QFile vendorIdentifier(QFileInfo(targetDir, QStringLiteral("idVendor")).absoluteFilePath());
if (vendorIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
serialPortInfo.d_ptr->vendorIdentifier = QString::fromLatin1(vendorIdentifier.readAll())
@@ -190,6 +194,9 @@ QList<QSerialPortInfo> availablePortsBySysfs()
.toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16);
}
// TODO: Obtain more information about the device
+ } else if (targetPath.contains(QStringLiteral(".serial/tty/tty"))) {
+ // This condition matches onboard serial port on embedded devices.
+ // Keep those devices in the list
} else {
continue;
}
@@ -345,12 +352,7 @@ QList<QSerialPortInfo> availablePortsByUdev()
QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
{
- QList<QSerialPortInfo> serialPortInfoList;
- // TODO: Remove this condition once the udev runtime symbol resolution crash
- // is fixed for Qt 4.
-#if defined(LINK_LIBUDEV) || (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
- serialPortInfoList = availablePortsByUdev();
-#endif
+ QList<QSerialPortInfo> serialPortInfoList = availablePortsByUdev();
#ifdef Q_OS_LINUX
if (serialPortInfoList.isEmpty())
diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp
index 82f7636..0958617 100644
--- a/src/serialport/qserialportinfo_win.cpp
+++ b/src/serialport/qserialportinfo_win.cpp
@@ -138,7 +138,7 @@ static QString deviceInstanceIdentifier(DEVINST deviceInstanceNumber)
outputBuffer.size(), 0) != CR_SUCCESS) {
return QString();
}
- return toStringAndTrimNullCharacter(outputBuffer);
+ return toStringAndTrimNullCharacter(outputBuffer).toUpper();
}
static DEVINST parentDeviceInstanceNumber(DEVINST childDeviceInstanceNumber)
@@ -282,7 +282,7 @@ static QString deviceSerialNumber(const QString &instanceIdentifier,
QString result = parseDeviceSerialNumber(instanceIdentifier);
if (result.isEmpty()) {
const DEVINST parentNumber = parentDeviceInstanceNumber(deviceInstanceNumber);
- const QString parentInstanceIdentifier = deviceInstanceIdentifier(parentNumber).toUpper();
+ const QString parentInstanceIdentifier = deviceInstanceIdentifier(parentNumber);
result = parseDeviceSerialNumber(parentInstanceIdentifier);
}
return result;
@@ -319,7 +319,7 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
serialPortInfo.d_ptr->description = deviceDescription(deviceInfoSet, &deviceInfoData);
serialPortInfo.d_ptr->manufacturer = deviceManufacturer(deviceInfoSet, &deviceInfoData);
- const QString instanceIdentifier = deviceInstanceIdentifier(deviceInfoData.DevInst).toUpper();
+ const QString instanceIdentifier = deviceInstanceIdentifier(deviceInfoData.DevInst);
serialPortInfo.d_ptr->serialNumber =
deviceSerialNumber(instanceIdentifier, deviceInfoData.DevInst);
diff --git a/src/serialport/qtudev_p.h b/src/serialport/qtudev_p.h
index f709f0c..c83a5c0 100644
--- a/src/serialport/qtudev_p.h
+++ b/src/serialport/qtudev_p.h
@@ -57,7 +57,7 @@ extern "C"
#define GENERATE_SYMBOL_VARIABLE(returnType, symbolName, ...) \
typedef returnType (*fp_##symbolName)(__VA_ARGS__); \
- fp_##symbolName symbolName;
+ static fp_##symbolName symbolName;
#define RESOLVE_SYMBOL(symbolName) \
symbolName = (fp_##symbolName)resolveSymbol(udevLibrary, #symbolName); \
diff --git a/tests/auto/qserialport/tst_qserialport.cpp b/tests/auto/qserialport/tst_qserialport.cpp
index d296f6d..357cef8 100644
--- a/tests/auto/qserialport/tst_qserialport.cpp
+++ b/tests/auto/qserialport/tst_qserialport.cpp
@@ -107,6 +107,11 @@ private slots:
void asynchronousWriteByTimer_data();
void asynchronousWriteByTimer();
+#ifdef Q_OS_WIN
+ void readBufferOverflow();
+ void readAfterInputClear();
+#endif
+
protected slots:
void handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten);
void handleBytesWrittenAndExitLoopSlot2(qint64 bytesWritten);
@@ -462,27 +467,27 @@ void tst_QSerialPort::twoStageSynchronousLoopback()
senderPort.waitForBytesWritten(waitMsecs);
QTest::qSleep(waitMsecs);
receiverPort.waitForReadyRead(waitMsecs);
- QCOMPARE(qint64(newlineArray.size()), receiverPort.bytesAvailable());
+ QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
receiverPort.write(receiverPort.readAll());
receiverPort.waitForBytesWritten(waitMsecs);
QTest::qSleep(waitMsecs);
senderPort.waitForReadyRead(waitMsecs);
- QCOMPARE(qint64(newlineArray.size()), receiverPort.bytesAvailable());
- QCOMPARE(newlineArray, senderPort.readAll());
+ QCOMPARE(senderPort.bytesAvailable(), qint64(newlineArray.size()));
+ QCOMPARE(senderPort.readAll(), newlineArray);
// second stage
senderPort.write(newlineArray);
senderPort.waitForBytesWritten(waitMsecs);
QTest::qSleep(waitMsecs);
receiverPort.waitForReadyRead(waitMsecs);
- QCOMPARE(qint64(newlineArray.size()), receiverPort.bytesAvailable());
+ QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
receiverPort.write(receiverPort.readAll());
receiverPort.waitForBytesWritten(waitMsecs);
QTest::qSleep(waitMsecs);
senderPort.waitForReadyRead(waitMsecs);
- QCOMPARE(qint64(newlineArray.size()), receiverPort.bytesAvailable());
- QCOMPARE(newlineArray, senderPort.readAll());
+ QCOMPARE(senderPort.bytesAvailable(), qint64(newlineArray.size()));
+ QCOMPARE(senderPort.readAll(), newlineArray);
}
void tst_QSerialPort::synchronousReadWrite()
@@ -508,7 +513,7 @@ void tst_QSerialPort::synchronousReadWrite()
while ((readData.size() < writeData.size()) && receiverPort.waitForReadyRead(100))
readData.append(receiverPort.readAll());
- QCOMPARE(writeData, readData);
+ QCOMPARE(readData, writeData);
}
class AsyncReader : public QObject
@@ -659,5 +664,77 @@ void tst_QSerialPort::asynchronousWriteByTimer()
QCOMPARE(receiverPort.readAll(), alphabetArray);
}
+#ifdef Q_OS_WIN
+void tst_QSerialPort::readBufferOverflow()
+{
+ clearReceiver();
+
+ QSerialPort senderPort(m_senderPortName);
+ QVERIFY(senderPort.open(QSerialPort::WriteOnly));
+
+ QSerialPort receiverPort(m_receiverPortName);
+ QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
+
+ const int readBufferSize = alphabetArray.size() / 2;
+ receiverPort.setReadBufferSize(readBufferSize);
+ QCOMPARE(receiverPort.readBufferSize(), qint64(readBufferSize));
+
+ QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));
+ QVERIFY2(senderPort.waitForBytesWritten(100), "Waiting for bytes written failed");
+
+ QByteArray readData;
+ while (receiverPort.waitForReadyRead(100)) {
+ QVERIFY(receiverPort.bytesAvailable() > 0);
+ readData += receiverPort.readAll();
+ }
+
+ QCOMPARE(readData, alphabetArray);
+
+ // No more bytes available
+ QVERIFY(receiverPort.bytesAvailable() == 0);
+}
+
+void tst_QSerialPort::readAfterInputClear()
+{
+ clearReceiver();
+
+ QSerialPort senderPort(m_senderPortName);
+ QVERIFY(senderPort.open(QSerialPort::WriteOnly));
+
+ QSerialPort receiverPort(m_receiverPortName);
+ QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
+
+ const int readBufferSize = alphabetArray.size() / 2;
+ receiverPort.setReadBufferSize(readBufferSize);
+ QCOMPARE(receiverPort.readBufferSize(), qint64(readBufferSize));
+
+ const int waitMsecs = 100;
+
+ // First write more than read buffer size
+ QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));
+ QVERIFY2(senderPort.waitForBytesWritten(waitMsecs), "Waiting for bytes written failed");
+
+ // Wait for first part of data into read buffer
+ while (receiverPort.waitForReadyRead(waitMsecs));
+ QCOMPARE(receiverPort.bytesAvailable(), qint64(readBufferSize));
+ // Wait for second part of data into driver's FIFO
+ QTest::qSleep(waitMsecs);
+
+ QVERIFY(receiverPort.clear(QSerialPort::Input));
+ QCOMPARE(receiverPort.bytesAvailable(), qint64(0));
+
+ // Second write less than read buffer size
+ QCOMPARE(senderPort.write(newlineArray), qint64(newlineArray.size()));
+ QVERIFY2(senderPort.waitForBytesWritten(waitMsecs), "Waiting for bytes written failed");
+
+ while (receiverPort.waitForReadyRead(waitMsecs));
+ QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
+ QCOMPARE(receiverPort.readAll(), newlineArray);
+
+ // No more bytes available
+ QVERIFY(receiverPort.bytesAvailable() == 0);
+}
+#endif
+
QTEST_MAIN(tst_QSerialPort)
#include "tst_qserialport.moc"