summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--dependencies.yaml7
-rw-r--r--examples/serialbus/can/connectdialog.cpp4
-rw-r--r--examples/serialbus/can/connectdialog.ui9
-rw-r--r--examples/serialbus/modbus/adueditor/plaintextedit.h5
-rw-r--r--src/plugins/canbus/passthrucan/passthrucanbackend.cpp2
-rw-r--r--src/plugins/canbus/peakcan/peakcan_symbols_p.h21
-rw-r--r--src/plugins/canbus/peakcan/peakcanbackend.cpp85
-rw-r--r--src/plugins/canbus/peakcan/peakcanbackend.h2
-rw-r--r--src/plugins/canbus/vectorcan/vectorcanbackend.cpp2
-rw-r--r--src/serialbus/doc/src/peakcan.qdoc12
-rw-r--r--src/serialbus/qcanbusdevice.cpp20
-rw-r--r--src/serialbus/qcanbusdevice.h4
-rw-r--r--src/serialbus/qcanbusdeviceinfo.cpp20
-rw-r--r--src/serialbus/qcanbusdeviceinfo.h1
-rw-r--r--src/serialbus/qcanbusdeviceinfo_p.h1
-rw-r--r--src/serialbus/qcanbusfactory.h4
-rw-r--r--src/serialbus/qmodbusclient_p.h1
-rw-r--r--src/serialbus/qmodbusdevice.cpp34
-rw-r--r--src/serialbus/qmodbusdevice.h17
-rw-r--r--src/serialbus/qmodbusdevice_p.h2
-rw-r--r--src/serialbus/qmodbuspdu.cpp2
-rw-r--r--src/serialbus/qmodbuspdu.h2
-rw-r--r--src/serialbus/qmodbusreply.cpp37
-rw-r--r--src/serialbus/qmodbusreply.h5
-rw-r--r--src/serialbus/qmodbusrtuserialmaster_p.h4
-rw-r--r--src/serialbus/qmodbustcpclient_p.h3
-rw-r--r--src/tools/canbusutil/canbusutil.cpp6
28 files changed, 274 insertions, 40 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 96f7a81..a93cfcc 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
CONFIG += warning_clean
DEFINES += QT_NO_FOREACH
-MODULE_VERSION = 5.15.0
+MODULE_VERSION = 6.0.0
diff --git a/dependencies.yaml b/dependencies.yaml
new file mode 100644
index 0000000..06ed447
--- /dev/null
+++ b/dependencies.yaml
@@ -0,0 +1,7 @@
+dependencies:
+ ../qtbase:
+ ref: 4c5f6eb74cfb3282513c0837c80a08705c1da844
+ required: true
+ ../qtserialport:
+ ref: 543e41db0f13f552c5bb36e58b39045b70f369b5
+ required: false
diff --git a/examples/serialbus/can/connectdialog.cpp b/examples/serialbus/can/connectdialog.cpp
index 601ef2c..a0430b4 100644
--- a/examples/serialbus/can/connectdialog.cpp
+++ b/examples/serialbus/can/connectdialog.cpp
@@ -120,6 +120,10 @@ void ConnectDialog::interfaceChanged(const QString &interface)
if (serialNumber.isEmpty())
serialNumber = tr("n/a");
m_ui->serialNumberLabel->setText(tr("Serial: %1").arg(serialNumber));
+ QString alias = info.alias();
+ if (alias.isEmpty())
+ alias = tr("n/a");
+ m_ui->aliasLabel->setText(tr("Alias: %1").arg(alias));
m_ui->channelLabel->setText(tr("Channel: %1").arg(info.channel()));
m_ui->isVirtual->setChecked(info.isVirtual());
m_ui->isFlexibleDataRateCapable->setChecked(info.hasFlexibleDataRate());
diff --git a/examples/serialbus/can/connectdialog.ui b/examples/serialbus/can/connectdialog.ui
index 6d4f261..b4ba898 100644
--- a/examples/serialbus/can/connectdialog.ui
+++ b/examples/serialbus/can/connectdialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>446</width>
- <height>395</height>
+ <height>418</height>
</rect>
</property>
<property name="windowTitle">
@@ -206,6 +206,13 @@
</widget>
</item>
<item>
+ <widget class="QLabel" name="aliasLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QLabel" name="channelLabel">
<property name="text">
<string/>
diff --git a/examples/serialbus/modbus/adueditor/plaintextedit.h b/examples/serialbus/modbus/adueditor/plaintextedit.h
index cbc590c..f5505fe 100644
--- a/examples/serialbus/modbus/adueditor/plaintextedit.h
+++ b/examples/serialbus/modbus/adueditor/plaintextedit.h
@@ -59,6 +59,11 @@ class PlainTextEdit : public QPlainTextEdit
Q_OBJECT
Q_DISABLE_COPY(PlainTextEdit)
+public Q_SLOT:
+ void setFocus() {
+ QWidget::setFocus();
+ }
+
public:
explicit PlainTextEdit(QWidget *parent = nullptr)
: QPlainTextEdit(parent)
diff --git a/src/plugins/canbus/passthrucan/passthrucanbackend.cpp b/src/plugins/canbus/passthrucan/passthrucanbackend.cpp
index 2c18160..380f6ea 100644
--- a/src/plugins/canbus/passthrucan/passthrucanbackend.cpp
+++ b/src/plugins/canbus/passthrucan/passthrucanbackend.cpp
@@ -200,7 +200,7 @@ bool PassThruCanBackend::open()
QByteArray subDev;
if (splitPos >= 0)
- subDev = m_deviceName.midRef(splitPos + 1).toLatin1();
+ subDev = QStringView{m_deviceName}.mid(splitPos + 1).toLatin1();
const QString library = libraryForAdapter(adapter);
if (library.isEmpty()) {
diff --git a/src/plugins/canbus/peakcan/peakcan_symbols_p.h b/src/plugins/canbus/peakcan/peakcan_symbols_p.h
index 12de76f..9031592 100644
--- a/src/plugins/canbus/peakcan/peakcan_symbols_p.h
+++ b/src/plugins/canbus/peakcan/peakcan_symbols_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com>
+** Copyright (c) 2020 Andre Hartmann <aha_1980@gmx.de>
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
@@ -168,7 +169,7 @@
#define PCAN_PCC 0x06U // PCAN-PC Card
// PCAN parameters
-#define PCAN_DEVICE_NUMBER 0x01U // PCAN-USB device number parameter
+#define PCAN_DEVICE_ID 0x01U // Device identifier parameter
#define PCAN_5VOLTS_POWER 0x02U // PCAN-PC Card 5-Volt power parameter
#define PCAN_RECEIVE_EVENT 0x03U // PCAN receive event handler parameter
#define PCAN_MESSAGE_FILTER 0x04U // PCAN message filter parameter
@@ -197,6 +198,8 @@
#define PCAN_BUSSPEED_DATA 0x1BU // Configured CAN data speed as Bits per seconds
#define PCAN_IP_ADDRESS 0x1CU // Remote address of a LAN channel as string in IPv4 format
#define PCAN_LAN_SERVICE_STATUS 0x1DU // Status of the Virtual PCAN-Gateway Service
+#define PCAN_ATTACHED_CHANNELS_COUNT 0x2AU // Get the amount of PCAN channels attached to a system
+#define PCAN_ATTACHED_CHANNELS 0x2BU // Get information about PCAN channels attached to a system
#define FEATURE_FD_CAPABLE 0x01U // Device supports flexible data-rate (CAN-FD)
@@ -225,6 +228,10 @@
#define TRACE_FILE_TIME 0x04U // Includes the start time into the name of the trace file
#define TRACE_FILE_OVERWRITE 0x80U // Causes the overwriting of available traces (same name)
+// Other constants
+#define MAX_LENGTH_HARDWARE_NAME 33 // Maximum length of the name of a device: 32 characters + terminator
+#define MAX_LENGTH_VERSION_STRING 18 // Maximum length of a version string: 17 characters + terminator
+
// PCAN message types
#define PCAN_MESSAGE_STANDARD 0x00U // The PCAN message is a CAN Standard Frame (11-bit identifier)
#define PCAN_MESSAGE_RTR 0x01U // The PCAN message is a CAN Remote-Transfer-Request Frame
@@ -312,6 +319,18 @@ typedef struct tagTPCANMsgFD
quint8 DATA[64]; // Data of the message (DATA[0]..DATA[63])
} TPCANMsgFD;
+// Describes an available PCAN channel
+typedef struct tagTPCANChannelInformation
+{
+ TPCANHandle channel_handle; // PCAN channel handle
+ TPCANDevice device_type; // Kind of PCAN device
+ quint8 controller_number; // CAN-Controller number
+ quint32 device_features; // Device capabilities flag (see FEATURE_*)
+ char device_name[MAX_LENGTH_HARDWARE_NAME]; // Device name
+ quint32 device_id; // Device number
+ quint32 channel_condition; // Availability status of a PCAN-Channel
+} TPCANChannelInformation;
+
#define GENERATE_SYMBOL_VARIABLE(returnType, symbolName, ...) \
typedef returnType (DRV_CALLBACK_TYPE *fp_##symbolName)(__VA_ARGS__); \
static fp_##symbolName symbolName;
diff --git a/src/plugins/canbus/peakcan/peakcanbackend.cpp b/src/plugins/canbus/peakcan/peakcanbackend.cpp
index 6e1af1c..0b4cf5b 100644
--- a/src/plugins/canbus/peakcan/peakcanbackend.cpp
+++ b/src/plugins/canbus/peakcan/peakcanbackend.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com>
+** Copyright (c) 2020 Andre Hartmann <aha_1980@gmx.de>
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
@@ -46,6 +47,7 @@
#include <QtCore/qloggingcategory.h>
#include <algorithm>
+#include <vector>
#ifdef Q_OS_WIN32
# include <QtCore/qwineventnotifier.h>
@@ -64,7 +66,7 @@ Q_GLOBAL_STATIC(QLibrary, pcanLibrary)
bool PeakCanBackend::canCreate(QString *errorReason)
{
#ifdef LINK_LIBPCANBASIC
- return true;
+ Q_UNUSED(errorReason);
#else
static bool symbolsResolved = resolvePeakCanSymbols(pcanLibrary());
if (Q_UNLIKELY(!symbolsResolved)) {
@@ -73,8 +75,17 @@ bool PeakCanBackend::canCreate(QString *errorReason)
*errorReason = pcanLibrary()->errorString();
return false;
}
- return true;
#endif
+
+ char apiVersion[32];
+ TPCANStatus stat = CAN_GetValue(PCAN_NONEBUS, PCAN_API_VERSION, apiVersion, sizeof(apiVersion));
+ if (Q_UNLIKELY(stat != PCAN_ERROR_OK)) {
+ qCWarning(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot resolve PCAN-API version!");
+ return false;
+ }
+ qCInfo(QT_CANBUS_PLUGINS_PEAKCAN, "Using PCAN-API version: %s", apiVersion);
+
+ return true;
}
struct PcanChannel{
@@ -117,7 +128,7 @@ static const PcanChannel pcanChannels[] = {
{ "none", PCAN_NONEBUS }
};
-QList<QCanBusDeviceInfo> PeakCanBackend::interfaces()
+QList<QCanBusDeviceInfo> PeakCanBackend::interfacesByChannelCondition()
{
QList<QCanBusDeviceInfo> result;
@@ -143,15 +154,81 @@ QList<QCanBusDeviceInfo> PeakCanBackend::interfaces()
if (chnStat != PCAN_ERROR_OK)
channel = 0;
+ QString alias;
+ quint32 deviceId = 0;
+ const TPCANStatus idStat = ::CAN_GetValue(index, PCAN_DEVICE_ID,
+ &deviceId, sizeof(deviceId));
+ if (idStat == PCAN_ERROR_OK)
+ alias = QString::number(deviceId);
+
result.append(std::move(createDeviceInfo(QLatin1String(pcanChannels[i].name),
QString(), QLatin1String(description),
- channel, false, isFd)));
+ alias, channel, false, isFd)));
+ }
+ }
+
+ return result;
+}
+
+QList<QCanBusDeviceInfo> PeakCanBackend::interfacesByAttachedChannels(bool *ok)
+{
+ *ok = true;
+ quint32 count = 0;
+ const TPCANStatus countStat = ::CAN_GetValue(0, PCAN_ATTACHED_CHANNELS_COUNT,
+ &count, sizeof(count));
+ if (Q_UNLIKELY(countStat != PCAN_ERROR_OK)) {
+ qCWarning(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot query PCAN_ATTACHED_CHANNELS_COUNT.");
+ *ok = false;
+ return {};
+ }
+ if (count == 0)
+ return {};
+
+ std::vector<TPCANChannelInformation> infos(count);
+ const TPCANStatus infosStat = ::CAN_GetValue(0, PCAN_ATTACHED_CHANNELS, infos.data(),
+ infos.size() * sizeof(TPCANChannelInformation));
+ if (Q_UNLIKELY(infosStat != PCAN_ERROR_OK)) {
+ qCWarning(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot query PCAN_ATTACHED_CHANNELS.");
+ *ok = false;
+ return {};
+ }
+
+ QList<QCanBusDeviceInfo> result;
+ for (quint32 i = 0; i < count; ++i) {
+ auto info = infos[i];
+ if (info.channel_condition & PCAN_CHANNEL_AVAILABLE) {
+ const quint32 deviceId = info.channel_handle;
+ const auto pcanChannel = std::find_if(std::begin(pcanChannels), std::end(pcanChannels),
+ [deviceId](PcanChannel channel) {
+ return channel.index == deviceId;
+ });
+ const QString name = pcanChannel->name;
+ const QString description = info.device_name;
+ const QString alias = QString::number(info.device_id);
+ const int channel = info.controller_number;
+ const bool isCanFd = (info.device_features & FEATURE_FD_CAPABLE);
+
+ result.append(std::move(createDeviceInfo(name, QString(), description, alias,
+ channel, false, isCanFd)));
}
}
return result;
}
+QList<QCanBusDeviceInfo> PeakCanBackend::interfaces()
+{
+#ifdef Q_OS_WIN
+ bool ok = false;
+ const QList<QCanBusDeviceInfo> attachedChannelsResult = interfacesByAttachedChannels(&ok);
+ if (ok)
+ return attachedChannelsResult;
+#endif
+
+ const QList<QCanBusDeviceInfo> result = interfacesByChannelCondition();
+ return result;
+}
+
#if defined(Q_OS_WIN32)
class PeakCanReadNotifier : public QWinEventNotifier
{
diff --git a/src/plugins/canbus/peakcan/peakcanbackend.h b/src/plugins/canbus/peakcan/peakcanbackend.h
index a9e108e..0ee74c3 100644
--- a/src/plugins/canbus/peakcan/peakcanbackend.h
+++ b/src/plugins/canbus/peakcan/peakcanbackend.h
@@ -69,6 +69,8 @@ public:
QString interpretErrorFrame(const QCanBusFrame &errorFrame) override;
static bool canCreate(QString *errorReason);
+ static QList<QCanBusDeviceInfo> interfacesByChannelCondition();
+ static QList<QCanBusDeviceInfo> interfacesByAttachedChannels(bool *ok);
static QList<QCanBusDeviceInfo> interfaces();
private:
diff --git a/src/plugins/canbus/vectorcan/vectorcanbackend.cpp b/src/plugins/canbus/vectorcan/vectorcanbackend.cpp
index 550f744..5d719d8 100644
--- a/src/plugins/canbus/vectorcan/vectorcanbackend.cpp
+++ b/src/plugins/canbus/vectorcan/vectorcanbackend.cpp
@@ -299,7 +299,7 @@ void VectorCanBackendPrivate::setupChannel(const QString &interfaceName)
{
Q_Q(VectorCanBackend);
if (Q_LIKELY(interfaceName.startsWith(QStringLiteral("can")))) {
- const QStringRef ref = interfaceName.midRef(3);
+ const QStringView ref = QStringView{interfaceName}.mid(3);
bool ok = false;
channelIndex = ref.toInt(&ok);
if (ok && (channelIndex >= 0 && channelIndex < XL_CONFIG_MAX_CHANNELS)) {
diff --git a/src/serialbus/doc/src/peakcan.qdoc b/src/serialbus/doc/src/peakcan.qdoc
index a38ddf7..c10263b 100644
--- a/src/serialbus/doc/src/peakcan.qdoc
+++ b/src/serialbus/doc/src/peakcan.qdoc
@@ -34,10 +34,13 @@
\l{http://www.peak-system.com/}{PEAK-System} CAN adapters.
This plugin requires the PCAN device drivers and the PCAN-Basic library
- version 4.0.0 or higher on Windows (pcanbasic.dll) and Linux (libpcanbasic.so).
- On macOS the plugin requires the PCBUSB library from
+ version 4.4.0 or higher on Windows (pcanbasic.dll) resp. 4.0.0 on Linux
+ (libpcanbasic.so). On macOS the plugin requires the PCBUSB library from
\l{http://www.mac-can.com}{UV Software}.
+ \note QCanBusDeviceInfo::alias() is only supported on Windows and with
+ PCAN-Basic 4.4.0 or higher.
+
\section1 Creating CAN Bus Devices
At first it is necessary to check that QCanBus provides the desired plugin:
@@ -126,6 +129,11 @@
\list
\li QCanBusDevice::resetController()
\li QCanBusDevice::busStatus()
+ \li QCanBusDeviceInfo::alias() (Windows and PCAN-Basic >= 4.4.0 only):
+ Returns the PCAN_DEVICE_ID which can be set to a user defined value
+ from 0..255 resp. 0..4294967295 (depending on the device) with PCAN-View.
+ The default value is 255 resp. 4294967295.
+
\endlist
*/
diff --git a/src/serialbus/qcanbusdevice.cpp b/src/serialbus/qcanbusdevice.cpp
index 5b6c343..eab2a7e 100644
--- a/src/serialbus/qcanbusdevice.cpp
+++ b/src/serialbus/qcanbusdevice.cpp
@@ -984,7 +984,8 @@ void QCanBusDevice::setState(QCanBusDevice::CanBusDeviceState newState)
QCanBusDeviceInfo QCanBusDevice::createDeviceInfo(const QString &name, bool isVirtual,
bool isFlexibleDataRateCapable)
{
- return createDeviceInfo(name, QString(), QString(), 0, isVirtual, isFlexibleDataRateCapable);
+ return createDeviceInfo(name, QString(), QString(), QString(),
+ 0, isVirtual, isFlexibleDataRateCapable);
}
/*!
@@ -998,10 +999,27 @@ QCanBusDeviceInfo QCanBusDevice::createDeviceInfo(const QString &name, const QSt
const QString &description, int channel,
bool isVirtual, bool isFlexibleDataRateCapable)
{
+ return createDeviceInfo(name, serialNumber, description, QString(),
+ channel, isVirtual, isFlexibleDataRateCapable);
+}
+
+/*!
+ \since 6.0
+ Returns a QCanBusDeviceInfo created from the given parameters \a name,
+ \a serialNumber, \a description, \a alias, \a channel, \a isVirtual,
+ and \a isFlexibleDataRateCapable.
+ \internal
+ */
+QCanBusDeviceInfo QCanBusDevice::createDeviceInfo(const QString &name, const QString &serialNumber,
+ const QString &description, const QString &alias,
+ int channel,
+ bool isVirtual, bool isFlexibleDataRateCapable)
+{
QScopedPointer<QCanBusDeviceInfoPrivate> info(new QCanBusDeviceInfoPrivate);
info->name = name;
info->serialNumber = serialNumber;
info->description = description;
+ info->alias = alias;
info->channel = channel;
info->hasFlexibleDataRate = isFlexibleDataRateCapable;
info->isVirtual = isVirtual;
diff --git a/src/serialbus/qcanbusdevice.h b/src/serialbus/qcanbusdevice.h
index 5d2d976..0afd896 100644
--- a/src/serialbus/qcanbusdevice.h
+++ b/src/serialbus/qcanbusdevice.h
@@ -191,6 +191,10 @@ protected:
static QCanBusDeviceInfo createDeviceInfo(const QString &name, const QString &serialNumber,
const QString &description, int channel,
bool isVirtual, bool isFlexibleDataRateCapable);
+ static QCanBusDeviceInfo createDeviceInfo(const QString &name, const QString &serialNumber,
+ const QString &description,
+ const QString &alias, int channel,
+ bool isVirtual, bool isFlexibleDataRateCapable);
};
Q_DECLARE_TYPEINFO(QCanBusDevice::CanBusError, Q_PRIMITIVE_TYPE);
diff --git a/src/serialbus/qcanbusdeviceinfo.cpp b/src/serialbus/qcanbusdeviceinfo.cpp
index 78dcd89..55d15df 100644
--- a/src/serialbus/qcanbusdeviceinfo.cpp
+++ b/src/serialbus/qcanbusdeviceinfo.cpp
@@ -110,6 +110,8 @@ QString QCanBusDeviceInfo::description() const
\since 5.11
Returns the serial number of the CAN bus interface as string, if available.
Otherwise, an empty string is returned.
+
+ \sa alias()
*/
QString QCanBusDeviceInfo::serialNumber() const
{
@@ -117,6 +119,24 @@ QString QCanBusDeviceInfo::serialNumber() const
}
/*!
+ \since 6.0
+ Returns a user defineable alias associated with this CAN bus interface.
+
+ Some CAN bus interfaces can have a user defined alias associated. This is mostly
+ done with the CAN hardware vendors tools. The alias allows to identify this
+ hardware later, especially when multiple interfaces are connected.
+
+ \note In contrast to serialNumber(), the alias is not guaranteed to be unique.
+
+ If that function is not supported by the CAN plugin, an empty string is returned.
+ \sa serialNumber()
+*/
+QString QCanBusDeviceInfo::alias() const
+{
+ return d_ptr->alias;
+}
+
+/*!
\since 5.11
Returns the sequential channel number of the CAN bus interface, starting
with zero. For example, a two channel CAN interface may have the channels
diff --git a/src/serialbus/qcanbusdeviceinfo.h b/src/serialbus/qcanbusdeviceinfo.h
index c46302d..487a94d 100644
--- a/src/serialbus/qcanbusdeviceinfo.h
+++ b/src/serialbus/qcanbusdeviceinfo.h
@@ -67,6 +67,7 @@ public:
QString name() const;
QString description() const;
QString serialNumber() const;
+ QString alias() const;
int channel() const;
bool hasFlexibleDataRate() const;
diff --git a/src/serialbus/qcanbusdeviceinfo_p.h b/src/serialbus/qcanbusdeviceinfo_p.h
index 78c9e1c..637343b 100644
--- a/src/serialbus/qcanbusdeviceinfo_p.h
+++ b/src/serialbus/qcanbusdeviceinfo_p.h
@@ -64,6 +64,7 @@ public:
QString name;
QString description;
QString serialNumber;
+ QString alias;
int channel = 0;
bool hasFlexibleDataRate = false;
bool isVirtual = false;
diff --git a/src/serialbus/qcanbusfactory.h b/src/serialbus/qcanbusfactory.h
index cd7322b..f8cb533 100644
--- a/src/serialbus/qcanbusfactory.h
+++ b/src/serialbus/qcanbusfactory.h
@@ -58,8 +58,8 @@ Q_DECLARE_INTERFACE(QCanBusFactory, "org.qt-project.Qt.QCanBusFactory")
class Q_SERIALBUS_EXPORT QCanBusFactoryV2 : public QCanBusFactory
{
public:
- virtual QCanBusDevice *createDevice(const QString &interfaceName,
- QString *errorMessage) const = 0;
+ QCanBusDevice *createDevice(const QString &interfaceName,
+ QString *errorMessage) const override = 0;
virtual QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const = 0;
protected:
diff --git a/src/serialbus/qmodbusclient_p.h b/src/serialbus/qmodbusclient_p.h
index f9a0dfb..05c799a 100644
--- a/src/serialbus/qmodbusclient_p.h
+++ b/src/serialbus/qmodbusclient_p.h
@@ -42,6 +42,7 @@
#include <QtSerialBus/qmodbuspdu.h>
#include <private/qmodbusdevice_p.h>
+#include <limits.h>
//
// W A R N I N G
diff --git a/src/serialbus/qmodbusdevice.cpp b/src/serialbus/qmodbusdevice.cpp
index ab8e126..32bd936 100644
--- a/src/serialbus/qmodbusdevice.cpp
+++ b/src/serialbus/qmodbusdevice.cpp
@@ -95,11 +95,6 @@ QModbusDevice::~QModbusDevice()
\value NetworkPortParameter This parameter holds the network port. \c int
\value NetworkAddressParameter This parameter holds the host address for network
communication. \c QString
-
- User options:
-
- \value UserParameter This enum value has been deprecated. There
- will be no replacement.
*/
/*!
@@ -120,7 +115,7 @@ QModbusDevice::~QModbusDevice()
\sa ConnectionParameter
*/
-QVariant QModbusDevice::connectionParameter(int parameter) const
+QVariant QModbusDevice::connectionParameter(ConnectionParameter parameter) const
{
Q_D(const QModbusDevice);
switch (parameter) {
@@ -143,7 +138,7 @@ QVariant QModbusDevice::connectionParameter(int parameter) const
default:
break;
}
- return d->m_userConnectionParams.value(parameter); // ### Qt6: remove
+ return {};
}
/*!
@@ -154,7 +149,7 @@ QVariant QModbusDevice::connectionParameter(int parameter) const
\sa ConnectionParameter
\sa connectionParameter()
*/
-void QModbusDevice::setConnectionParameter(int parameter, const QVariant &value)
+void QModbusDevice::setConnectionParameter(ConnectionParameter parameter, const QVariant &value)
{
Q_D(QModbusDevice);
switch (parameter) {
@@ -182,7 +177,7 @@ void QModbusDevice::setConnectionParameter(int parameter, const QVariant &value)
d->m_networkAddress = value.toString();
break;
default:
- d->m_userConnectionParams.insert(parameter, value); // ### Qt6: remove
+ Q_ASSERT_X(false, "", "Connection parameter not supported.");
break;
}
}
@@ -217,6 +212,27 @@ void QModbusDevice::setConnectionParameter(int parameter, const QVariant &value)
*/
/*!
+ \since 6.0
+ \enum QModbusDevice::IntermediateError
+
+ This enum describes possible errors that can happen during a full send and
+ receive cycle for a Modbus reply.
+
+ \value ResponseCrcError A Modbus response with a wrong CRC was received.
+ \value ResponseRequestMismatch A Modbus response was received but did not
+ match the open request, probably due to the
+ PDU's function code not matching.
+
+ If any of the above intermediate errors occurred, the frame is likely
+ resent until the maximum number of retries has been reached.
+
+ The list of intermediate errors can be inspected from the \l QModbusReply
+ intermediate errors function.
+
+ \sa QModbusClient::numberOfRetries(), QModbusReply::intermediateErrors()
+*/
+
+/*!
\fn QModbusDevice::errorOccurred(QModbusDevice::Error error)
This signal is emitted when an error of the type, \a error, occurs.
diff --git a/src/serialbus/qmodbusdevice.h b/src/serialbus/qmodbusdevice.h
index 0e6dad7..e620613 100644
--- a/src/serialbus/qmodbusdevice.h
+++ b/src/serialbus/qmodbusdevice.h
@@ -79,18 +79,22 @@ public:
SerialStopBitsParameter,
NetworkPortParameter,
- NetworkAddressParameter,
-
- // Reserved
- UserParameter = 0x100 // ### Qt6: remove
+ NetworkAddressParameter
};
Q_ENUM(ConnectionParameter)
+ enum IntermediateError
+ {
+ ResponseCrcError,
+ ResponseRequestMismatch
+ };
+ Q_ENUM(IntermediateError)
+
explicit QModbusDevice(QObject *parent = nullptr);
~QModbusDevice();
- QVariant connectionParameter(int parameter) const;
- void setConnectionParameter(int parameter, const QVariant &value);
+ QVariant connectionParameter(ConnectionParameter parameter) const;
+ void setConnectionParameter(ConnectionParameter parameter, const QVariant &value);
bool connectDevice();
void disconnectDevice();
@@ -118,6 +122,7 @@ protected:
Q_DECLARE_TYPEINFO(QModbusDevice::Error, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QModbusDevice::State, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QModbusDevice::ConnectionParameter, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QModbusDevice::IntermediateError, Q_PRIMITIVE_TYPE);
QT_END_NAMESPACE
diff --git a/src/serialbus/qmodbusdevice_p.h b/src/serialbus/qmodbusdevice_p.h
index 1526397..c60ffc4 100644
--- a/src/serialbus/qmodbusdevice_p.h
+++ b/src/serialbus/qmodbusdevice_p.h
@@ -78,8 +78,6 @@ public:
int m_networkPort = 502;
QString m_networkAddress = QStringLiteral("127.0.0.1");
- QHash<int, QVariant> m_userConnectionParams; // ### Qt6: remove
-
virtual QIODevice *device() const { return nullptr; }
};
diff --git a/src/serialbus/qmodbuspdu.cpp b/src/serialbus/qmodbuspdu.cpp
index 9ca9027..1f13a0e 100644
--- a/src/serialbus/qmodbuspdu.cpp
+++ b/src/serialbus/qmodbuspdu.cpp
@@ -439,7 +439,7 @@ static QDataStream &pduFromStream(QDataStream &stream, QModbusPdu &pdu, Type typ
QDebug operator<<(QDebug debug, const QModbusPdu &pdu)
{
QDebugStateSaver _(debug);
- debug.nospace().noquote() << "0x" << Qt::hex << qSetFieldWidth(2) << qSetPadChar('0')
+ debug.nospace().noquote() << "0x" << Qt::hex << qSetFieldWidth(2) << qSetPadChar(u'0')
<< (pdu.isException() ? pdu.functionCode() | QModbusPdu::ExceptionByte : pdu.functionCode())
<< qSetFieldWidth(0) << pdu.data().toHex();
return debug;
diff --git a/src/serialbus/qmodbuspdu.h b/src/serialbus/qmodbuspdu.h
index e93ec4c..f0542d9 100644
--- a/src/serialbus/qmodbuspdu.h
+++ b/src/serialbus/qmodbuspdu.h
@@ -249,7 +249,7 @@ public:
: QModbusResponse(FunctionCode(quint8(fc) | ExceptionByte), static_cast<quint8> (ec))
{}
- void setFunctionCode(FunctionCode c) {
+ void setFunctionCode(FunctionCode c) override {
QModbusPdu::setFunctionCode(FunctionCode(quint8(c) | ExceptionByte));
}
void setExceptionCode(ExceptionCode ec) { QModbusPdu::encodeData(quint8(ec)); }
diff --git a/src/serialbus/qmodbusreply.cpp b/src/serialbus/qmodbusreply.cpp
index caa2dd9..e5561c2 100644
--- a/src/serialbus/qmodbusreply.cpp
+++ b/src/serialbus/qmodbusreply.cpp
@@ -53,6 +53,7 @@ public:
QString m_errorText;
QModbusResponse m_response;
QModbusReply::ReplyType m_type;
+ QVector<QModbusDevice::IntermediateError> m_intermediateErrors;
};
/*!
@@ -239,7 +240,6 @@ QString QModbusReply::errorString() const
return d->m_errorText;
}
-
/*!
Returns the type of the reply.
@@ -278,6 +278,41 @@ void QModbusReply::setRawResult(const QModbusResponse &response)
d->m_response = response;
}
+/*!
+ \since 6.0
+ \fn void intermediateErrorOccurred(QModbusDevice::IntermediateError error)
+
+ This signal is emitted when an error has been detected in the processing of
+ this reply. The error will be described by the error code \a error.
+*/
+
+/*!
+ \since 6.0
+
+ Returns the list of intermediate errors that might have happened during
+ the send-receive cycle of a Modbus request until the QModbusReply reports
+ to be finished.
+*/
+QVector<QModbusDevice::IntermediateError> QModbusReply::intermediateErrors() const
+{
+ Q_D(const QModbusReply);
+ return d->m_intermediateErrors;
+}
+
+/*!
+ \internal
+ \since 6.0
+
+ Adds an intermediate error to the list of intermediate errors.
+ This will also cause the \l intermediateErrorOccurred() signal to be emitted.
+*/
+void QModbusReply::addIntermediateError(QModbusDevice::IntermediateError error)
+{
+ Q_D(QModbusReply);
+ d->m_intermediateErrors.append(error);
+ emit intermediateErrorOccurred(error);
+}
+
QT_END_NAMESPACE
#include "moc_qmodbusreply.cpp"
diff --git a/src/serialbus/qmodbusreply.h b/src/serialbus/qmodbusreply.h
index ffefc89..7381912 100644
--- a/src/serialbus/qmodbusreply.h
+++ b/src/serialbus/qmodbusreply.h
@@ -37,6 +37,7 @@
#ifndef QMODBUSREPLY_H
#define QMODBUSREPLY_H
+#include <QtCore/qvector.h>
#include <QtSerialBus/qmodbusdataunit.h>
#include <QtSerialBus/qmodbusdevice.h>
#include <QtSerialBus/qmodbuspdu.h>
@@ -77,9 +78,13 @@ public:
void setFinished(bool isFinished);
void setError(QModbusDevice::Error error, const QString &errorText);
+ QVector<QModbusDevice::IntermediateError> intermediateErrors() const;
+ void addIntermediateError(QModbusDevice::IntermediateError error);
+
Q_SIGNALS:
void finished();
void errorOccurred(QModbusDevice::Error error);
+ void intermediateErrorOccurred(QModbusDevice::IntermediateError error);
};
Q_DECLARE_TYPEINFO(QModbusReply::ReplyType, Q_PRIMITIVE_TYPE);
diff --git a/src/serialbus/qmodbusrtuserialmaster_p.h b/src/serialbus/qmodbusrtuserialmaster_p.h
index d206eec..4c75951 100644
--- a/src/serialbus/qmodbusrtuserialmaster_p.h
+++ b/src/serialbus/qmodbusrtuserialmaster_p.h
@@ -98,7 +98,7 @@ private:
class QModbusRtuSerialMasterPrivate : public QModbusClientPrivate
{
Q_DECLARE_PUBLIC(QModbusRtuSerialMaster)
- enum State
+ enum State
{
Idle,
WaitingForReplay,
@@ -165,6 +165,7 @@ public:
qCWarning(QT_MODBUS) << "(RTU client) Discarding response with wrong CRC, received:"
<< adu.checksum<quint16>() << ", calculated CRC:"
<< QModbusSerialAdu::calculateCRC(adu.data(), adu.size());
+ m_queue.first().reply->addIntermediateError(QModbusClient::ResponseCrcError);
return;
}
@@ -172,6 +173,7 @@ public:
if (!canMatchRequestAndResponse(response, adu.serverAddress())) {
qCWarning(QT_MODBUS) << "(RTU client) Cannot match response with open request, "
"ignoring";
+ m_queue.first().reply->addIntermediateError(QModbusClient::ResponseRequestMismatch);
return;
}
diff --git a/src/serialbus/qmodbustcpclient_p.h b/src/serialbus/qmodbustcpclient_p.h
index 4c574a1..cdac792 100644
--- a/src/serialbus/qmodbustcpclient_p.h
+++ b/src/serialbus/qmodbustcpclient_p.h
@@ -86,8 +86,7 @@ public:
cleanupTransactionStore();
});
- QObject::connect(m_socket,
- &QAbstractSocket::errorOccurred, q,
+ QObject::connect(m_socket, &QAbstractSocket::errorOccurred, q,
[this](QAbstractSocket::SocketError /*error*/)
{
Q_Q(QModbusTcpClient);
diff --git a/src/tools/canbusutil/canbusutil.cpp b/src/tools/canbusutil/canbusutil.cpp
index b07d97c..9b34fac 100644
--- a/src/tools/canbusutil/canbusutil.cpp
+++ b/src/tools/canbusutil/canbusutil.cpp
@@ -133,7 +133,7 @@ bool CanBusUtil::parseDataField(quint32 &id, QString &payload)
return false;
}
- id = m_data.leftRef(hashMarkPos).toUInt(nullptr, 16);
+ id = QStringView{m_data}.left(hashMarkPos).toUInt(nullptr, 16);
payload = m_data.right(m_data.size() - hashMarkPos - 1);
return true;
@@ -148,7 +148,7 @@ bool CanBusUtil::setFrameFromPayload(QString payload, QCanBusFrame *frame)
return true;
bool ok = false;
- int rtrFrameLength = payload.midRef(1).toInt(&ok);
+ int rtrFrameLength = QStringView{payload}.mid(1).toInt(&ok);
if (ok && rtrFrameLength >= 0 && rtrFrameLength <= 8) { // payload = "R8"
frame->setPayload(QByteArray(rtrFrameLength, 0));
return true;
@@ -172,7 +172,7 @@ bool CanBusUtil::setFrameFromPayload(QString payload, QCanBusFrame *frame)
if (payload.size() % 2 != 0) {
if (frame->hasFlexibleDataRateFormat()) {
enum { BitrateSwitchFlag = 1, ErrorStateIndicatorFlag = 2 };
- const int flags = payload.leftRef(1).toInt(nullptr, 16);
+ const int flags = QStringView{payload}.left(1).toInt(nullptr, 16);
frame->setBitrateSwitch(flags & BitrateSwitchFlag);
frame->setErrorStateIndicator(flags & ErrorStateIndicatorFlag);
payload.remove(0, 1);