summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Roquetto <rafael.roquetto@kdab.com>2014-04-25 19:20:56 -0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-05-14 15:43:55 +0200
commitd913488a75acabff3497b5f0b6c5fa29158fbd63 (patch)
tree649398382c582e93ca10fe7213e557411b49373f
parent4b34f99e837b8fff9e690e63f80da76805a4686f (diff)
downloadqtserialport-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.cpp158
-rw-r--r--src/serialport/qserialport_unix_p.h9
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, &currentSerialInfo) != -1) {
- // prepare section
+ currentSerialInfo.flags &= ~ASYNC_SPD_CUST;
+ currentSerialInfo.custom_divisor = 0;
+
+ ::ioctl(descriptor, TIOCSSERIAL, &currentSerialInfo);
+ }
+
+ return !(((directions & QSerialPort::Input) && ::cfsetispeed(&currentTermios, baudRate) < 0)
+ || ((directions & QSerialPort::Output) && ::cfsetospeed(&currentTermios, baudRate) < 0));
+}
+#else
+
+bool QSerialPortPrivate::setStandardBaudRate(qint32 baudRate,
+ QSerialPort::Directions directions)
+{
+ return !(((directions & QSerialPort::Input) && ::cfsetispeed(&currentTermios, baudRate) < 0)
+ || ((directions & QSerialPort::Output) && ::cfsetospeed(&currentTermios, 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(&currentTermios, unixBaudRate) < 0)
- || ((directions & QSerialPort::Output) && ::cfsetospeed(&currentTermios, 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(&currentTermios, B38400) != -1) && (::cfsetospeed(&currentTermios, 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, &currentSerialInfo) == -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, &currentSerialInfo) == -1)
+ return false;
+
+ return !(((directions & QSerialPort::Input) && ::cfsetispeed(&currentTermios, B38400) < 0)
+ || ((directions & QSerialPort::Output) && ::cfsetospeed(&currentTermios, 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, &currentSerialInfo) != -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;