summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2018-02-27 16:49:48 +0100
committerAlex Blasche <alexander.blasche@qt.io>2018-10-24 06:01:31 +0000
commitfcf05e2399a2d94af1c6a907221a95e3ab96ed1d (patch)
tree81c407b179223db2491b6f941cd86ed010cf2acc
parent682c5ca041483b7d3e8994e7fac5bcab6327e5c2 (diff)
Fix RTU Master ignoring responses due to being in Send state
The fix for QTBUG-62299 limits the processing of serial responses in RTU serial master to cases when the state machine is in receive mode only. So far the Receive state was triggered by the sendTimer. However modern kernels accept serial packages faster then the sendTimer can fire. This patches addresses the problem by setting the Receive state even before sendTimer fires. If the bytesWritten() callback detects that the entire PDU/ADU was written it stops sendTimer and immediately progresses the state machine to the Receive state. Fixes: QTBUG-69188 Change-Id: I1657973ef99f1b3e4008e887029b30890d825d59 Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
-rw-r--r--src/serialbus/qmodbusrtuserialmaster_p.h13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/serialbus/qmodbusrtuserialmaster_p.h b/src/serialbus/qmodbusrtuserialmaster_p.h
index 9a75de5..104c365 100644
--- a/src/serialbus/qmodbusrtuserialmaster_p.h
+++ b/src/serialbus/qmodbusrtuserialmaster_p.h
@@ -151,8 +151,10 @@ public:
return;
}
- if (m_state != State::Receive)
+ if (m_state != State::Receive) {
+ qCDebug(QT_MODBUS) << "(RTU server) Ignoring response due to non receive state";
return;
+ }
m_sendTimer.stop();
m_responseTimer.stop();
@@ -215,6 +217,13 @@ public:
QObject::connect(m_serialPort, &QSerialPort::bytesWritten, q, [this](qint64 bytes) {
m_current.bytesWritten += bytes;
+ if (m_state == Send && (m_current.bytesWritten == m_current.adu.size()) && !m_current.reply.isNull()) {
+ // the if conditions above are copied from processQueue()
+ qCDebug(QT_MODBUS) << "(RTU client) Send successful (quick):" << m_current.requestPdu;
+ m_state = Receive;
+ m_sendTimer.stop();
+ m_responseTimer.start(m_responseTimeoutDuration);
+ }
});
QObject::connect(m_serialPort, &QSerialPort::aboutToClose, q, [this]() {
@@ -321,7 +330,7 @@ public:
break;
case Send:
- // send timeout will always happen
+ // send timeout will always happen unless cancelled by very quick bytesWritten
if (m_current.reply.isNull()) {
scheduleNextRequest();
} else if (m_current.bytesWritten < m_current.adu.size()) {