summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2015-09-10 16:25:15 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2015-09-24 15:34:43 +0000
commita1655d6ccf3f82508286b471819cc5e5cb64ff44 (patch)
treedd1ef288de9177462c55b5597d52f8de7d8fd37f
parent918b22aef140d293721f0d81ea8988c1d35db582 (diff)
downloadqtserialport-a1655d6ccf3f82508286b471819cc5e5cb64ff44.tar.gz
Cleanup remainders of code relating to data error policy handling
It is impossible to implement all these features on all platforms, and particular drivers may not support them, too. Consequently, the user should handle such errors themselves by applying platform-specific ioctls on the device descriptor and/or parsing the stream's byte-stuffing. This commit also deprecates ParityError, FramingError, and BreakConditionError. Tested on Windows and Linux with the virtual and the USB serial ports. Change-Id: I4ffc2f067787bc304a83326acb2a2421b428f986 Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com> Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/serialport/qserialport.cpp24
-rw-r--r--src/serialport/qserialport.h8
-rw-r--r--src/serialport/qserialport_p.h8
-rw-r--r--src/serialport/qserialport_unix.cpp134
-rw-r--r--src/serialport/qserialport_win.cpp68
-rw-r--r--src/serialport/qserialport_wince.cpp58
6 files changed, 26 insertions, 274 deletions
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp
index 071e33d..690eb65 100644
--- a/src/serialport/qserialport.cpp
+++ b/src/serialport/qserialport.cpp
@@ -63,15 +63,6 @@ QSerialPortErrorInfo::QSerialPortErrorInfo(QSerialPort::SerialPortError newError
case QSerialPort::TimeoutError:
errorString = QSerialPort::tr("Operation timed out");
break;
- case QSerialPort::ParityError:
- errorString = QSerialPort::tr("Parity error detected while reading");
- break;
- case QSerialPort::BreakConditionError:
- errorString = QSerialPort::tr("Break condition detected while reading");
- break;
- case QSerialPort::FramingError:
- errorString = QSerialPort::tr("Framing error detected while reading");
- break;
case QSerialPort::ReadError:
errorString = QSerialPort::tr("Error reading from device");
break;
@@ -99,18 +90,15 @@ QSerialPortPrivate::QSerialPortPrivate()
, parity(QSerialPort::NoParity)
, stopBits(QSerialPort::OneStop)
, flowControl(QSerialPort::NoFlowControl)
- , policy(QSerialPort::IgnorePolicy)
#if QT_DEPRECATED_SINCE(5,3)
, settingsRestoredOnClose(true)
#endif
, isBreakEnabled(false)
#if defined(Q_OS_WINCE)
, handle(INVALID_HANDLE_VALUE)
- , parityErrorOccurred(false)
, eventNotifier(0)
#elif defined(Q_OS_WIN32)
, handle(INVALID_HANDLE_VALUE)
- , parityErrorOccurred(false)
, readChunkBuffer(ReadChunkSize, 0)
, communicationStarted(false)
, writeStarted(false)
@@ -417,13 +405,16 @@ void QSerialPortPrivate::setError(const QSerialPortErrorInfo &errorInfo)
QtSerialPort 5.2.
\value ParityError Parity error detected by the hardware while
- reading data.
+ reading data. This value is obsolete. We strongly
+ advise against using it in new code.
\value FramingError Framing error detected by the hardware while
- reading data.
+ reading data. This value is obsolete. We strongly
+ advise against using it in new code.
\value BreakConditionError Break condition detected by the hardware on
- the input line.
+ the input line. This value is obsolete. We strongly
+ advise against using it in new code.
\value WriteError An I/O error occurred while writing the data.
@@ -1147,8 +1138,7 @@ bool QSerialPort::setDataErrorPolicy(DataErrorPolicy policy)
QSerialPort::DataErrorPolicy QSerialPort::dataErrorPolicy() const
{
- Q_D(const QSerialPort);
- return d->policy;
+ return QSerialPort::IgnorePolicy;
}
#endif // QT_DEPRECATED_SINCE(5, 2)
diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h
index 2815ebe..a19e1bf 100644
--- a/src/serialport/qserialport.h
+++ b/src/serialport/qserialport.h
@@ -186,6 +186,14 @@ public:
};
Q_ENUM(SerialPortError)
+#if QT_DEPRECATED_SINCE(5, 6)
+#if defined(_MSC_VER)
+#pragma deprecated(ParityError)
+#pragma deprecated(FramingError)
+#pragma deprecated(BreakConditionError)
+#endif
+#endif
+
explicit QSerialPort(QObject *parent = Q_NULLPTR);
explicit QSerialPort(const QString &name, QObject *parent = Q_NULLPTR);
explicit QSerialPort(const QSerialPortInfo &info, QObject *parent = Q_NULLPTR);
diff --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h
index 6ad7c26..d2527e3 100644
--- a/src/serialport/qserialport_p.h
+++ b/src/serialport/qserialport_p.h
@@ -151,7 +151,6 @@ public:
bool setParity(QSerialPort::Parity parity);
bool setStopBits(QSerialPort::StopBits stopBits);
bool setFlowControl(QSerialPort::FlowControl flowControl);
- bool setDataErrorPolicy(QSerialPort::DataErrorPolicy policy);
QSerialPortErrorInfo getSystemError(int systemErrorCode = -1) const;
@@ -177,7 +176,6 @@ public:
QSerialPort::Parity parity;
QSerialPort::StopBits stopBits;
QSerialPort::FlowControl flowControl;
- QSerialPort::DataErrorPolicy policy;
bool settingsRestoredOnClose;
bool isBreakEnabled;
@@ -190,7 +188,6 @@ public:
bool waitForReadOrWrite(bool *selectForRead, bool *selectForWrite,
bool checkRead, bool checkWrite,
int msecs);
- void processIoErrors(bool error);
bool notifyRead();
bool notifyWrite();
@@ -200,7 +197,6 @@ public:
COMMTIMEOUTS currentCommTimeouts;
COMMTIMEOUTS restoredCommTimeouts;
HANDLE handle;
- bool parityErrorOccurred;
QThread *eventNotifier;
QMutex settingsChangeMutex;
@@ -211,7 +207,6 @@ public:
bool setDcb(DCB *dcb);
bool getDcb(DCB *dcb);
bool updateCommTimeouts();
- void handleLineStatusErrors();
OVERLAPPED *waitForNotified(int msecs);
bool completeAsyncCommunication(qint64 bytesTransferred);
@@ -223,14 +218,12 @@ public:
bool _q_startAsyncWrite();
void _q_notified(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
- bool emulateErrorPolicy();
void emitReadyRead();
DCB restoredDcb;
COMMTIMEOUTS currentCommTimeouts;
COMMTIMEOUTS restoredCommTimeouts;
HANDLE handle;
- bool parityErrorOccurred;
QByteArray readChunkBuffer;
bool communicationStarted;
bool writeStarted;
@@ -268,7 +261,6 @@ public:
#ifndef CMSPAR
qint64 writePerChar(const char *data, qint64 maxSize);
#endif
- qint64 readPerChar(char *data, qint64 maxSize);
bool readNotification();
bool startAsyncWrite();
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index f058acf..4659a18 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -714,50 +714,13 @@ bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flowControl)
return setTermios(&tio);
}
-bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy)
-{
- termios tio;
- if (!getTermios(&tio))
- return false;
-
- tcflag_t parmrkMask = PARMRK;
-#ifndef CMSPAR
- // in space/mark parity emulation also used PARMRK flag
- if (parity == QSerialPort::SpaceParity
- || parity == QSerialPort::MarkParity) {
- parmrkMask = 0;
- }
-#endif //CMSPAR
- switch (policy) {
- case QSerialPort::SkipPolicy:
- tio.c_iflag &= ~parmrkMask;
- tio.c_iflag |= IGNPAR | INPCK;
- break;
- case QSerialPort::PassZeroPolicy:
- tio.c_iflag &= ~(IGNPAR | parmrkMask);
- tio.c_iflag |= INPCK;
- break;
- case QSerialPort::IgnorePolicy:
- tio.c_iflag &= ~INPCK;
- break;
- case QSerialPort::StopReceivingPolicy:
- tio.c_iflag &= ~IGNPAR;
- tio.c_iflag |= parmrkMask | INPCK;
- break;
- default:
- tio.c_iflag &= ~INPCK;
- break;
- }
- return setTermios(&tio);
-}
-
bool QSerialPortPrivate::readNotification()
{
Q_Q(QSerialPort);
// Always buffered, read data from the port into the read buffer
qint64 newBytes = buffer.size();
- qint64 bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1;
+ qint64 bytesToRead = ReadChunkSize;
if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - buffer.size())) {
bytesToRead = readBufferMaxSize - buffer.size();
@@ -1049,20 +1012,7 @@ bool QSerialPortPrivate::waitForReadOrWrite(bool *selectForRead, bool *selectFor
qint64 QSerialPortPrivate::readFromPort(char *data, qint64 maxSize)
{
- qint64 bytesRead = 0;
-#if defined(CMSPAR)
- if (parity == QSerialPort::NoParity
- || policy != QSerialPort::StopReceivingPolicy) {
-#else
- if (parity != QSerialPort::MarkParity
- && parity != QSerialPort::SpaceParity) {
-#endif
- bytesRead = qt_safe_read(descriptor, data, maxSize);
- } else {// Perform parity emulation.
- bytesRead = readPerChar(data, maxSize);
- }
-
- return bytesRead;
+ return qt_safe_read(descriptor, data, maxSize);
}
qint64 QSerialPortPrivate::writeToPort(const char *data, qint64 maxSize)
@@ -1082,6 +1032,8 @@ qint64 QSerialPortPrivate::writeToPort(const char *data, qint64 maxSize)
return bytesWritten;
}
+#ifndef CMSPAR
+
static inline bool evenParity(quint8 c)
{
c ^= c >> 4; //(c7 ^ c3)(c6 ^ c2)(c5 ^ c1)(c4 ^ c0)
@@ -1090,8 +1042,6 @@ static inline bool evenParity(quint8 c)
return c & 1; //(c7 ^ c3)(c5 ^ c1)(c6 ^ c2)(c4 ^ c0)
}
-#ifndef CMSPAR
-
qint64 QSerialPortPrivate::writePerChar(const char *data, qint64 maxSize)
{
termios tio;
@@ -1127,82 +1077,6 @@ qint64 QSerialPortPrivate::writePerChar(const char *data, qint64 maxSize)
#endif //CMSPAR
-qint64 QSerialPortPrivate::readPerChar(char *data, qint64 maxSize)
-{
- termios tio;
- if (!getTermios(&tio))
- return -1;
-
- qint64 ret = 0;
- quint8 const charMask = (0xFF >> (8 - dataBits));
-
- // 0 - prefix not started,
- // 1 - received 0xFF,
- // 2 - received 0xFF and 0x00
- int prefix = 0;
- while (ret < maxSize) {
-
- qint64 r = qt_safe_read(descriptor, data, 1);
- if (r < 0) {
- if (errno == EAGAIN) // It is ok for nonblocking mode.
- break;
- return -1;
- }
- if (r == 0)
- break;
-
- bool par = true;
- switch (prefix) {
- case 2: // Previously received both 0377 and 0.
- par = false;
- prefix = 0;
- break;
- case 1: // Previously received 0377.
- if (*data == '\0') {
- ++prefix;
- continue;
- }
- prefix = 0;
- break;
- default:
- if (*data == '\377') {
- prefix = 1;
- continue;
- }
- break;
- }
- // Now: par contains parity ok or error, *data contains received character
- par ^= evenParity(*data & charMask); //par contains parity bit value for EVEN mode
- par ^= (tio.c_cflag & PARODD); //par contains parity bit value for current mode
- if (par ^ (parity == QSerialPort::SpaceParity)) { //if parity error
- switch (policy) {
- case QSerialPort::SkipPolicy:
- continue; //ignore received character
- case QSerialPort::StopReceivingPolicy: {
- if (parity != QSerialPort::NoParity)
- setError(QSerialPortErrorInfo(QSerialPort::ParityError));
- else if (*data == '\0')
- setError(QSerialPortErrorInfo(QSerialPort::BreakConditionError));
- else
- setError(QSerialPortErrorInfo(QSerialPort::FramingError));
- return ++ret; //abort receiving
- }
- break;
- case QSerialPort::UnknownPolicy:
- // Unknown error policy is used! Falling back to PassZeroPolicy
- case QSerialPort::PassZeroPolicy:
- *data = '\0'; //replace received character by zero
- break;
- case QSerialPort::IgnorePolicy:
- break; //ignore error and pass received character
- }
- }
- ++data;
- ++ret;
- }
- return ret;
-}
-
typedef QMap<qint32, qint32> BaudRateMap;
// The OS specific defines can be found in termios.h
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index 540b169..39d7e33 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE
bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
DWORD desiredAccess = 0;
- originalEventMask = EV_ERR;
+ originalEventMask = 0;
if (mode & QIODevice::ReadOnly) {
desiredAccess |= GENERIC_READ;
@@ -123,8 +123,6 @@ void QSerialPortPrivate::close()
writeBuffer.clear();
actualBytesToWrite = 0;
- parityErrorOccurred = false;
-
if (settingsRestoredOnClose) {
if (!::SetCommState(handle, &restoredDcb))
setError(getSystemError());
@@ -418,20 +416,12 @@ bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flowControl)
return setDcb(&dcb);
}
-bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy)
-{
- policy = policy;
- return true;
-}
-
bool QSerialPortPrivate::completeAsyncCommunication(qint64 bytesTransferred)
{
communicationStarted = false;
if (bytesTransferred == qint64(-1))
return false;
- if (EV_ERR & triggeredEventMask)
- handleLineStatusErrors();
return startAsyncRead();
}
@@ -450,12 +440,12 @@ bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred)
readStarted = false;
bool result = true;
- if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
+ if (bytesTransferred == ReadChunkSize)
result = startAsyncRead();
else if (readBufferMaxSize == 0 || readBufferMaxSize > buffer.size())
result = startAsyncCommunication();
- if ((bytesTransferred > 0) && !emulateErrorPolicy())
+ if (bytesTransferred > 0)
emitReadyRead();
return result;
@@ -503,7 +493,7 @@ bool QSerialPortPrivate::startAsyncRead()
if (readStarted)
return true;
- DWORD bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1;
+ DWORD bytesToRead = ReadChunkSize;
if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - buffer.size())) {
bytesToRead = readBufferMaxSize - buffer.size();
@@ -576,34 +566,6 @@ void QSerialPortPrivate::_q_notified(DWORD numberOfBytes, DWORD errorCode, OVERL
Q_ASSERT(!"Unknown OVERLAPPED activated");
}
-bool QSerialPortPrivate::emulateErrorPolicy()
-{
- if (!parityErrorOccurred)
- return false;
-
- parityErrorOccurred = false;
-
- switch (policy) {
- case QSerialPort::SkipPolicy:
- buffer.getChar();
- break;
- case QSerialPort::PassZeroPolicy:
- buffer.getChar();
- buffer.ungetChar('\0');
- emitReadyRead();
- break;
- case QSerialPort::IgnorePolicy:
- return false;
- case QSerialPort::StopReceivingPolicy:
- emitReadyRead();
- break;
- default:
- return false;
- }
-
- return true;
-}
-
void QSerialPortPrivate::emitReadyRead()
{
Q_Q(QSerialPort);
@@ -629,26 +591,6 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
return maxSize;
}
-void QSerialPortPrivate::handleLineStatusErrors()
-{
- DWORD errors = 0;
- if (!::ClearCommError(handle, &errors, Q_NULLPTR)) {
- setError(getSystemError());
- return;
- }
-
- if (errors & CE_FRAME) {
- setError(QSerialPortErrorInfo(QSerialPort::FramingError));
- } else if (errors & CE_RXPARITY) {
- setError(QSerialPortErrorInfo(QSerialPort::FramingError));
- parityErrorOccurred = true;
- } else if (errors & CE_BREAK) {
- setError(QSerialPortErrorInfo(QSerialPort::BreakConditionError));
- } else {
- setError(QSerialPortErrorInfo(QSerialPort::UnknownError, QSerialPort::tr("Unknown streaming error")));
- }
-}
-
OVERLAPPED *QSerialPortPrivate::waitForNotified(int msecs)
{
OVERLAPPED *overlapped = notifier->waitForAnyNotified(msecs);
@@ -706,7 +648,7 @@ inline bool QSerialPortPrivate::initialize()
notifier->setHandle(handle);
notifier->setEnabled(true);
- if (!startAsyncCommunication())
+ if ((originalEventMask & EV_RXCHAR) && !startAsyncCommunication())
return false;
return true;
diff --git a/src/serialport/qserialport_wince.cpp b/src/serialport/qserialport_wince.cpp
index 4f475d6..18dd15d 100644
--- a/src/serialport/qserialport_wince.cpp
+++ b/src/serialport/qserialport_wince.cpp
@@ -119,8 +119,6 @@ private slots:
error = true;
}
- if (error || (EV_ERR & eventMask))
- dptr->processIoErrors(error);
if (EV_RXCHAR & eventMask)
dptr->notifyRead();
if (EV_TXEMPTY & eventMask)
@@ -179,7 +177,7 @@ private:
bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
DWORD desiredAccess = 0;
- DWORD eventMask = EV_ERR;
+ DWORD eventMask = 0;
if (mode & QIODevice::ReadOnly) {
desiredAccess |= GENERIC_READ;
@@ -463,17 +461,11 @@ bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flowControl)
return updateDcb();
}
-bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy)
-{
- policy = policy;
- return true;
-}
-
bool QSerialPortPrivate::notifyRead()
{
Q_Q(QSerialPort);
- DWORD bytesToRead = (policy == QSerialPort::IgnorePolicy) ? ReadChunkSize : 1;
+ DWORD bytesToRead = ReadChunkSize;
if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - buffer.size())) {
bytesToRead = readBufferMaxSize - buffer.size();
@@ -497,27 +489,6 @@ bool QSerialPortPrivate::notifyRead()
buffer.chop(bytesToRead - qMax(readBytes, DWORD(0)));
- // Process emulate policy.
- if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) {
-
- parityErrorOccurred = false;
-
- switch (policy) {
- case QSerialPort::SkipPolicy:
- buffer.getChar();
- return true;
- case QSerialPort::PassZeroPolicy:
- buffer.getChar();
- buffer.ungetChar('\0');
- break;
- case QSerialPort::StopReceivingPolicy:
- // FIXME: Maybe need disable read notifier?
- break;
- default:
- break;
- }
- }
-
if (readBytes > 0)
emit q->readyRead();
@@ -554,31 +525,6 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
return maxSize;
}
-void QSerialPortPrivate::processIoErrors(bool hasError)
-{
- if (hasError) {
- setError(QSerialPortErrorInfo(QSerialPort::ResourceError));
- return;
- }
-
- DWORD errors = 0;
- if (!::ClearCommError(handle, &errors, Q_NULLPTR)) {
- setError(getSystemError());
- return;
- }
-
- if (errors & CE_FRAME) {
- setError(QSerialPortErrorInfo(QSerialPort::FramingError));
- } else if (errors & CE_RXPARITY) {
- setError(QSerialPortErrorInfo(QSerialPort::FramingError));
- parityErrorOccurred = true;
- } else if (errors & CE_BREAK) {
- setError(QSerialPortErrorInfo(QSerialPort::BreakConditionError));
- } else {
- setError(QSerialPortErrorInfo(QSerialPort::UnknownError, QSerialPort::tr("Unknown streaming error")));
- }
-}
-
inline bool QSerialPortPrivate::initialize(DWORD eventMask)
{
Q_Q(QSerialPort);