diff options
author | Karsten Heimrich <karsten.heimrich@qt.io> | 2019-03-20 14:49:57 +0100 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@qt.io> | 2019-04-01 09:03:03 +0000 |
commit | 10b10aeb9b912165a7769bfed38c8f23e5762d4e (patch) | |
tree | 32beeb05dfe0093564702d33f8795851cfb9e4cb /src/serialbus/qmodbusrtuserialmaster_p.h | |
parent | 20f68cefe6d9a4c073721855053076cb63980a83 (diff) |
Move lambda code into separate functions
Change-Id: I259175817d5767c7cf24c6f04f4faae190f773ed
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/serialbus/qmodbusrtuserialmaster_p.h')
-rw-r--r-- | src/serialbus/qmodbusrtuserialmaster_p.h | 287 |
1 files changed, 155 insertions, 132 deletions
diff --git a/src/serialbus/qmodbusrtuserialmaster_p.h b/src/serialbus/qmodbusrtuserialmaster_p.h index 5e440b2..75d06ec 100644 --- a/src/serialbus/qmodbusrtuserialmaster_p.h +++ b/src/serialbus/qmodbusrtuserialmaster_p.h @@ -76,163 +76,186 @@ class QModbusRtuSerialMasterPrivate : public QModbusClientPrivate } m_state = Idle; public: - void setupSerialPort() + void onReadyRead() { - Q_Q(QModbusRtuSerialMaster); + responseBuffer += m_serialPort->read(m_serialPort->bytesAvailable()); + qCDebug(QT_MODBUS_LOW) << "(RTU client) Response buffer:" << responseBuffer.toHex(); - m_sendTimer.setSingleShot(true); - QObject::connect(&m_sendTimer, &QTimer::timeout, q, [this]() { processQueue(); }); + if (responseBuffer.size() < 2) { + qCDebug(QT_MODBUS) << "(RTU client) Modbus ADU not complete"; + return; + } - m_responseTimer.setSingleShot(true); - QObject::connect(&m_responseTimer, &QTimer::timeout, q, [this]() { processQueue(); }); + const QModbusSerialAdu tmpAdu(QModbusSerialAdu::Rtu, responseBuffer); + int pduSizeWithoutFcode = QModbusResponse::calculateDataSize(tmpAdu.pdu()); + if (pduSizeWithoutFcode < 0) { + // wait for more data + qCDebug(QT_MODBUS) << "(RTU client) Cannot calculate PDU size for function code:" + << tmpAdu.pdu().functionCode() << ", delaying pending frame"; + return; + } - m_serialPort = new QSerialPort(q); - QObject::connect(m_serialPort, &QSerialPort::readyRead, q, [this]() { - responseBuffer += m_serialPort->read(m_serialPort->bytesAvailable()); - qCDebug(QT_MODBUS_LOW) << "(RTU client) Response buffer:" << responseBuffer.toHex(); + // server address byte + function code byte + PDU size + 2 bytes CRC + int aduSize = 2 + pduSizeWithoutFcode + 2; + if (tmpAdu.rawSize() < aduSize) { + qCDebug(QT_MODBUS) << "(RTU client) Incomplete ADU received, ignoring"; + return; + } - if (responseBuffer.size() < 2) { - qCDebug(QT_MODBUS) << "(RTU client) Modbus ADU not complete"; - return; + // Special case for Diagnostics:ReturnQueryData. The response has no + // length indicator and is just a simple echo of what we have send. + if (tmpAdu.pdu().functionCode() == QModbusPdu::Diagnostics) { + const QModbusResponse response = tmpAdu.pdu(); + if (canMatchRequestAndResponse(response, tmpAdu.serverAddress())) { + quint16 subCode = 0xffff; + response.decodeData(&subCode); + if (subCode == Diagnostics::ReturnQueryData) { + if (response.data() != m_current.requestPdu.data()) + return; // echo does not match request yet + aduSize = 2 + response.dataSize() + 2; + if (tmpAdu.rawSize() < aduSize) + return; // echo matches, probably checksum missing + } } + } - const QModbusSerialAdu tmpAdu(QModbusSerialAdu::Rtu, responseBuffer); - int pduSizeWithoutFcode = QModbusResponse::calculateDataSize(tmpAdu.pdu()); - if (pduSizeWithoutFcode < 0) { - // wait for more data - qCDebug(QT_MODBUS) << "(RTU client) Cannot calculate PDU size for function code:" - << tmpAdu.pdu().functionCode() << ", delaying pending frame"; - return; - } + const QModbusSerialAdu adu(QModbusSerialAdu::Rtu, responseBuffer.left(aduSize)); + responseBuffer.remove(0, aduSize); - // server address byte + function code byte + PDU size + 2 bytes CRC - int aduSize = 2 + pduSizeWithoutFcode + 2; - if (tmpAdu.rawSize() < aduSize) { - qCDebug(QT_MODBUS) << "(RTU client) Incomplete ADU received, ignoring"; - return; - } + qCDebug(QT_MODBUS) << "(RTU client) Received ADU:" << adu.rawData().toHex(); + if (QT_MODBUS().isDebugEnabled() && !responseBuffer.isEmpty()) + qCDebug(QT_MODBUS_LOW) << "(RTU client) Pending buffer:" << responseBuffer.toHex(); - // Special case for Diagnostics:ReturnQueryData. The response has no - // length indicator and is just a simple echo of what we have send. - if (tmpAdu.pdu().functionCode() == QModbusPdu::Diagnostics) { - const QModbusResponse response = tmpAdu.pdu(); - if (canMatchRequestAndResponse(response, tmpAdu.serverAddress())) { - quint16 subCode = 0xffff; - response.decodeData(&subCode); - if (subCode == Diagnostics::ReturnQueryData) { - if (response.data() != m_current.requestPdu.data()) - return; // echo does not match request yet - aduSize = 2 + response.dataSize() + 2; - if (tmpAdu.rawSize() < aduSize) - return; // echo matches, probably checksum missing - } - } - } + // check CRC + if (!adu.matchingChecksum()) { + qCWarning(QT_MODBUS) << "(RTU client) Discarding response with wrong CRC, received:" + << adu.checksum<quint16>() << ", calculated CRC:" + << QModbusSerialAdu::calculateCRC(adu.data(), adu.size()); + return; + } - const QModbusSerialAdu adu(QModbusSerialAdu::Rtu, responseBuffer.left(aduSize)); - responseBuffer.remove(0, aduSize); + const QModbusResponse response = adu.pdu(); + if (!canMatchRequestAndResponse(response, adu.serverAddress())) { + qCWarning(QT_MODBUS) << "(RTU client) Cannot match response with open request, " + "ignoring"; + return; + } - qCDebug(QT_MODBUS)<< "(RTU client) Received ADU:" << adu.rawData().toHex(); - if (QT_MODBUS().isDebugEnabled() && !responseBuffer.isEmpty()) - qCDebug(QT_MODBUS_LOW) << "(RTU client) Pending buffer:" << responseBuffer.toHex(); + if (m_state != State::Receive) { + qCDebug(QT_MODBUS) << "(RTU server) Ignoring response due to non receive state"; + return; + } - // check CRC - if (!adu.matchingChecksum()) { - qCWarning(QT_MODBUS) << "(RTU client) Discarding response with wrong CRC, received:" - << adu.checksum<quint16>() << ", calculated CRC:" - << QModbusSerialAdu::calculateCRC(adu.data(), adu.size()); - return; - } + m_sendTimer.stop(); + m_responseTimer.stop(); + processQueueElement(response, m_current); - const QModbusResponse response = adu.pdu(); - if (!canMatchRequestAndResponse(response, adu.serverAddress())) { - qCWarning(QT_MODBUS) << "(RTU client) Cannot match response with open request, " - "ignoring"; - return; - } + m_state = Schedule; // reschedule, even if empty + m_serialPort->clear(QSerialPort::AllDirections); + QTimer::singleShot(m_interFrameDelayMilliseconds, [this]() { processQueue(); }); + } - if (m_state != State::Receive) { - qCDebug(QT_MODBUS) << "(RTU server) Ignoring response due to non receive state"; - return; - } + void onAboutToClose() + { + Q_Q(QModbusRtuSerialMaster); + Q_UNUSED(q) // avoid warning in release mode + Q_ASSERT(q->state() == QModbusDevice::ClosingState); + m_sendTimer.stop(); + m_responseTimer.stop(); + } + + void onBytesWritten(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.stop(); - processQueueElement(response, m_current); + m_responseTimer.start(m_responseTimeoutDuration); + } + } + + void onError(QSerialPort::SerialPortError error) + { + if (error == QSerialPort::NoError) + return; + + qCDebug(QT_MODBUS) << "(RTU server) QSerialPort error:" << error + << (m_serialPort ? m_serialPort->errorString() : QString()); - m_state = Schedule; // reschedule, even if empty - m_serialPort->clear(QSerialPort::AllDirections); - QTimer::singleShot(m_interFrameDelayMilliseconds, [this]() { processQueue(); }); + Q_Q(QModbusRtuSerialMaster); + + switch (error) { + case QSerialPort::DeviceNotFoundError: + q->setError(QModbusDevice::tr("Referenced serial device does not exist."), + QModbusDevice::ConnectionError); + break; + case QSerialPort::PermissionError: + q->setError(QModbusDevice::tr("Cannot open serial device due to permissions."), + QModbusDevice::ConnectionError); + break; + case QSerialPort::OpenError: + case QSerialPort::NotOpenError: + q->setError(QModbusDevice::tr("Cannot open serial device."), + QModbusDevice::ConnectionError); + break; + case QSerialPort::WriteError: + q->setError(QModbusDevice::tr("Write error."), QModbusDevice::WriteError); + break; + case QSerialPort::ReadError: + q->setError(QModbusDevice::tr("Read error."), QModbusDevice::ReadError); + break; + case QSerialPort::ResourceError: + q->setError(QModbusDevice::tr("Resource error."), QModbusDevice::ConnectionError); + break; + case QSerialPort::UnsupportedOperationError: + q->setError(QModbusDevice::tr("Device operation is not supported error."), + QModbusDevice::ConfigurationError); + break; + case QSerialPort::TimeoutError: + q->setError(QModbusDevice::tr("Timeout error."), QModbusDevice::TimeoutError); + break; + case QSerialPort::UnknownError: + q->setError(QModbusDevice::tr("Unknown error."), QModbusDevice::UnknownError); + break; + default: + qCDebug(QT_MODBUS) << "(RTU server) Unhandled QSerialPort error" << error; + break; + } + } + + void setupSerialPort() + { + Q_Q(QModbusRtuSerialMaster); + m_serialPort = new QSerialPort(q); + + m_sendTimer.setSingleShot(true); + QObject::connect(&m_sendTimer, &QTimer::timeout, q, [this]() { + processQueue(); }); - using TypeId = void (QSerialPort::*)(QSerialPort::SerialPortError); - QObject::connect(m_serialPort, static_cast<TypeId>(&QSerialPort::error), - [this](QSerialPort::SerialPortError error) { - if (error == QSerialPort::NoError) - return; - - qCDebug(QT_MODBUS) << "(RTU server) QSerialPort error:" << error - << (m_serialPort ? m_serialPort->errorString() : QString()); - - Q_Q(QModbusRtuSerialMaster); - - switch (error) { - case QSerialPort::DeviceNotFoundError: - q->setError(QModbusDevice::tr("Referenced serial device does not exist."), - QModbusDevice::ConnectionError); - break; - case QSerialPort::PermissionError: - q->setError(QModbusDevice::tr("Cannot open serial device due to permissions."), - QModbusDevice::ConnectionError); - break; - case QSerialPort::OpenError: - case QSerialPort::NotOpenError: - q->setError(QModbusDevice::tr("Cannot open serial device."), - QModbusDevice::ConnectionError); - break; - case QSerialPort::WriteError: - q->setError(QModbusDevice::tr("Write error."), QModbusDevice::WriteError); - break; - case QSerialPort::ReadError: - q->setError(QModbusDevice::tr("Read error."), QModbusDevice::ReadError); - break; - case QSerialPort::ResourceError: - q->setError(QModbusDevice::tr("Resource error."), QModbusDevice::ConnectionError); - break; - case QSerialPort::UnsupportedOperationError: - q->setError(QModbusDevice::tr("Device operation is not supported error."), - QModbusDevice::ConfigurationError); - break; - case QSerialPort::TimeoutError: - q->setError(QModbusDevice::tr("Timeout error."), QModbusDevice::TimeoutError); - break; - case QSerialPort::UnknownError: - q->setError(QModbusDevice::tr("Unknown error."), QModbusDevice::UnknownError); - break; - default: - qCDebug(QT_MODBUS) << "(RTU server) Unhandled QSerialPort error" << error; - break; - } + m_responseTimer.setSingleShot(true); + QObject::connect(&m_responseTimer, &QTimer::timeout, q, [this]() { + processQueue(); }); - 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::readyRead, q, [this]() { + onReadyRead(); }); QObject::connect(m_serialPort, &QSerialPort::aboutToClose, q, [this]() { - Q_Q(QModbusRtuSerialMaster); - Q_UNUSED(q); // To avoid unused variable warning in release mode - Q_ASSERT(q->state() == QModbusDevice::ClosingState); + onAboutToClose(); + }); - m_sendTimer.stop(); - m_responseTimer.stop(); + QObject::connect(m_serialPort, &QSerialPort::bytesWritten, q, [this](qint64 bytes) { + onBytesWritten(bytes); + }); + + QObject::connect(m_serialPort, QOverload<QSerialPort::SerialPortError>::of(&QSerialPort::error), + q, [this](QSerialPort::SerialPortError error) { + onError(error); }); } |