diff options
author | Rafael Roquetto <rafael.roquetto@kdab.com> | 2014-04-25 19:20:56 -0300 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-14 15:43:55 +0200 |
commit | d913488a75acabff3497b5f0b6c5fa29158fbd63 (patch) | |
tree | 649398382c582e93ca10fe7213e557411b49373f | |
parent | 4b34f99e837b8fff9e690e63f80da76805a4686f (diff) | |
download | qtserialport-d913488a75acabff3497b5f0b6c5fa29158fbd63.tar.gz |
Refactor QSerialPortPrivate::setBaudRate()
Split platform specific functions into their own setCustomBaudRate() methods to
improve readability.
As a side-effect, remove isCustomBaudRateSupported flag.
Change-Id: Ia26d5472219756fbf186c78aa049bba72966d7b5
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com>
-rw-r--r-- | src/serialport/qserialport_unix.cpp | 158 | ||||
-rw-r--r-- | src/serialport/qserialport_unix_p.h | 9 |
2 files changed, 98 insertions, 69 deletions
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index 04bb6a8..50695fa 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -173,7 +173,6 @@ private: QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) : QSerialPortPrivateData(q) , descriptor(-1) - , isCustomBaudRateSupported(false) , readNotifier(0) , writeNotifier(0) , exceptionNotifier(0) @@ -279,13 +278,6 @@ void QSerialPortPrivate::close() if (settingsRestoredOnClose) { if (::tcsetattr(descriptor, TCSANOW, &restoredTermios) == -1) q->setError(decodeSystemError()); - -#ifdef Q_OS_LINUX - if (isCustomBaudRateSupported) { - if (::ioctl(descriptor, TIOCSSERIAL, &restoredSerialInfo) == -1) - q->setError(decodeSystemError()); - } -#endif } #ifdef TIOCNXCL @@ -318,7 +310,6 @@ void QSerialPortPrivate::close() lockFileScopedPointer->unlock(); descriptor = -1; - isCustomBaudRateSupported = false; pendingBytesWritten = 0; writeSequenceStarted = false; } @@ -532,76 +523,115 @@ bool QSerialPortPrivate::setBaudRate() && setBaudRate(outputBaudRate, QSerialPort::Output)); } -bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions directions) +#if defined(Q_OS_LINUX) + +bool QSerialPortPrivate::setStandardBaudRate(qint32 baudRate, + QSerialPort::Directions directions) { - Q_Q(QSerialPort); + struct serial_struct currentSerialInfo; - bool ret = baudRate > 0; + if (::ioctl(descriptor, TIOCGSERIAL, ¤tSerialInfo) != -1) { - // prepare section + currentSerialInfo.flags &= ~ASYNC_SPD_CUST; + currentSerialInfo.custom_divisor = 0; + + ::ioctl(descriptor, TIOCSSERIAL, ¤tSerialInfo); + } + + return !(((directions & QSerialPort::Input) && ::cfsetispeed(¤tTermios, baudRate) < 0) + || ((directions & QSerialPort::Output) && ::cfsetospeed(¤tTermios, baudRate) < 0)); +} +#else + +bool QSerialPortPrivate::setStandardBaudRate(qint32 baudRate, + QSerialPort::Directions directions) +{ + return !(((directions & QSerialPort::Input) && ::cfsetispeed(¤tTermios, baudRate) < 0) + || ((directions & QSerialPort::Output) && ::cfsetospeed(¤tTermios, baudRate) < 0)); +} - if (ret) { - const qint32 unixBaudRate = QSerialPortPrivate::settingFromBaudRate(baudRate); - if (unixBaudRate > 0) { - // try prepate to set standard baud rate -#ifdef Q_OS_LINUX - // prepare to forcefully reset the custom mode - if (isCustomBaudRateSupported) { - //currentSerialInfo.flags |= ASYNC_SPD_MASK; - currentSerialInfo.flags &= ~(ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/); - currentSerialInfo.custom_divisor = 0; - } #endif - // prepare to set standard baud rate - ret = !(((directions & QSerialPort::Input) && ::cfsetispeed(¤tTermios, unixBaudRate) < 0) - || ((directions & QSerialPort::Output) && ::cfsetospeed(¤tTermios, unixBaudRate) < 0)); - } else { - // try prepate to set custom baud rate -#ifdef Q_OS_LINUX - // prepare to forcefully set the custom mode - if (isCustomBaudRateSupported) { - currentSerialInfo.flags &= ~ASYNC_SPD_MASK; - currentSerialInfo.flags |= (ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/); - currentSerialInfo.custom_divisor = currentSerialInfo.baud_base / baudRate; - if (currentSerialInfo.custom_divisor == 0) - currentSerialInfo.custom_divisor = 1; - // for custom mode needed prepare to set B38400 baud rate - ret = (::cfsetispeed(¤tTermios, B38400) != -1) && (::cfsetospeed(¤tTermios, B38400) != -1); - } else { - ret = false; - } + +#if defined(Q_OS_LINUX) + +bool QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions) +{ + Q_UNUSED(directions); + + struct serial_struct currentSerialInfo; + + if (::ioctl(descriptor, TIOCGSERIAL, ¤tSerialInfo) == -1) + return false; + + if (currentSerialInfo.baud_base % baudRate != 0) { + Q_Q(QSerialPort); + q->setError(QSerialPort::UnsupportedOperationError); + + return false; + } + + currentSerialInfo.flags &= ~ASYNC_SPD_MASK; + currentSerialInfo.flags |= (ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/); + currentSerialInfo.custom_divisor = currentSerialInfo.baud_base / baudRate; + + if (currentSerialInfo.custom_divisor == 0) + currentSerialInfo.custom_divisor = 1; + + if (::ioctl(descriptor, TIOCSSERIAL, ¤tSerialInfo) == -1) + return false; + + return !(((directions & QSerialPort::Input) && ::cfsetispeed(¤tTermios, B38400) < 0) + || ((directions & QSerialPort::Output) && ::cfsetospeed(¤tTermios, B38400) < 0)); +} + #elif defined(Q_OS_MAC) -# if defined (MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) - // Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates - // other than those specified by POSIX. The driver for the underlying serial hardware - // ultimately determines which baud rates can be used. This ioctl sets both the input - // and output speed. - ret = ::ioctl(descriptor, IOSSIOSPEED, &baudRate) != -1; -# else - // others MacOSX version, can't prepare to set custom baud rate - ret = false; -# endif +bool QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions) +{ + Q_UNUSED(directions); + +#if defined (MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) + return (::ioctl(descriptor, IOSSIOSPEED, &baudRate) != -1); +#endif + return false; +} #else - // others *nix OS, can't prepare to set custom baud rate - ret = false; + +bool QSerialPortPrivate::setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions) +{ + Q_UNUSED(baudRate); + Q_UNUSED(directions); + + return false; +} + #endif - } + +bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions directions) +{ + Q_Q(QSerialPort); + + if (baudRate <= 0) { + q->setError(QSerialPort::UnsupportedOperationError); + return false; } - // finally section + q->setError(QSerialPort::NoError); -#ifdef Q_OS_LINUX - if (ret && isCustomBaudRateSupported) // finally, set or reset the custom mode - ret = ::ioctl(descriptor, TIOCSSERIAL, ¤tSerialInfo) != -1; -#endif + const qint32 unixBaudRate = QSerialPortPrivate::settingFromBaudRate(baudRate); + + const bool ok = (unixBaudRate > 0) + ? setStandardBaudRate(unixBaudRate, directions) + : setCustomBaudRate(baudRate, directions); + + if (ok) + return updateTermios(); - if (ret) // finally, set baud rate - ret = updateTermios(); - else + if (q->error() == QSerialPort::NoError) q->setError(decodeSystemError()); - return ret; + + return false; } bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits) diff --git a/src/serialport/qserialport_unix_p.h b/src/serialport/qserialport_unix_p.h index 97a88c0..0691cf1 100644 --- a/src/serialport/qserialport_unix_p.h +++ b/src/serialport/qserialport_unix_p.h @@ -136,12 +136,7 @@ public: struct termios currentTermios; struct termios restoredTermios; -#ifdef Q_OS_LINUX - struct serial_struct currentSerialInfo; - struct serial_struct restoredSerialInfo; -#endif int descriptor; - bool isCustomBaudRateSupported; QSocketNotifier *readNotifier; QSocketNotifier *writeNotifier; @@ -161,6 +156,10 @@ public: private: bool updateTermios(); + bool setCustomBaudRate(qint32 baudRate, + QSerialPort::Directions directions); + bool setStandardBaudRate(qint32 baudRate, + QSerialPort::Directions directions); QSerialPort::SerialPortError decodeSystemError() const; |