diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2015-09-10 16:25:15 +0300 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2015-09-24 16:22:58 +0000 |
commit | 2e7e58c7f225ee2237b27285c19a060a277e35fe (patch) | |
tree | b7b8e53103713abc588c2a4edf23c67a0ea1f8e7 /src/serialport/qserialport_unix.cpp | |
parent | 5c0fed7b7c19641e0dcc7740277ac5f54422b4bf (diff) | |
download | qtserialport-2e7e58c7f225ee2237b27285c19a060a277e35fe.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.
(cherry-picked from a1655d6ccf3f82508286b471819cc5e5cb64ff44)
Change-Id: I4ffc2f067787bc304a83326acb2a2421b428f986
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Diffstat (limited to 'src/serialport/qserialport_unix.cpp')
-rw-r--r-- | src/serialport/qserialport_unix.cpp | 134 |
1 files changed, 4 insertions, 130 deletions
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index 284dc76..7c18d08 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -731,50 +731,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 = readBuffer.size(); - qint64 bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1; + qint64 bytesToRead = ReadChunkSize; if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) { bytesToRead = readBufferMaxSize - readBuffer.size(); @@ -1066,20 +1029,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) @@ -1099,6 +1049,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) @@ -1107,8 +1059,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; @@ -1144,82 +1094,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 |