diff options
Diffstat (limited to 'src/plugins/canbus')
51 files changed, 1138 insertions, 1758 deletions
diff --git a/src/plugins/canbus/CMakeLists.txt b/src/plugins/canbus/CMakeLists.txt new file mode 100644 index 0000000..e86e0c6 --- /dev/null +++ b/src/plugins/canbus/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(virtualcan) +if(QT_FEATURE_socketcan) + add_subdirectory(socketcan) +endif() +if(QT_FEATURE_library) + add_subdirectory(passthrucan) + add_subdirectory(peakcan) + add_subdirectory(tinycan) +endif() +if(QT_FEATURE_library AND WIN32) + add_subdirectory(systeccan) +endif() +if(QT_FEATURE_library AND WIN32 AND NOT WINRT) + add_subdirectory(vectorcan) +endif() diff --git a/src/plugins/canbus/canbus.pro b/src/plugins/canbus/canbus.pro deleted file mode 100644 index ab9755c..0000000 --- a/src/plugins/canbus/canbus.pro +++ /dev/null @@ -1,18 +0,0 @@ -TEMPLATE = subdirs - -include($$OUT_PWD/../../serialbus/qtserialbus-config.pri) -QT_FOR_CONFIG += serialbus-private - -SUBDIRS += virtualcan - -qtConfig(socketcan) { - SUBDIRS += socketcan -} - -qtConfig(library) { - SUBDIRS += passthrucan peakcan tinycan - win32 { - SUBDIRS += systeccan - !winrt:SUBDIRS += vectorcan - } -} diff --git a/src/plugins/canbus/passthrucan/CMakeLists.txt b/src/plugins/canbus/passthrucan/CMakeLists.txt new file mode 100644 index 0000000..1884aed --- /dev/null +++ b/src/plugins/canbus/passthrucan/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## PassThruCanBusPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(PassThruCanBusPlugin + OUTPUT_NAME qtpassthrucanbus + PLUGIN_TYPE canbus + SOURCES + j2534passthru.cpp j2534passthru.h + main.cpp + passthrucanbackend.cpp passthrucanbackend.h + passthrucanio.cpp passthrucanio.h + LIBRARIES + Qt::Network + Qt::SerialBus +) diff --git a/src/plugins/canbus/passthrucan/j2534passthru.cpp b/src/plugins/canbus/passthrucan/j2534passthru.cpp index 22bf996..e8967d7 100644 --- a/src/plugins/canbus/passthrucan/j2534passthru.cpp +++ b/src/plugins/canbus/passthrucan/j2534passthru.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Ford Motor Company. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Ford Motor Company. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "j2534passthru.h" diff --git a/src/plugins/canbus/passthrucan/j2534passthru.h b/src/plugins/canbus/passthrucan/j2534passthru.h index a9b88f4..b65534f 100644 --- a/src/plugins/canbus/passthrucan/j2534passthru.h +++ b/src/plugins/canbus/passthrucan/j2534passthru.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Ford Motor Company. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Ford Motor Company. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef PASSTHRUCAN_J2534PASSTHRU_H #define PASSTHRUCAN_J2534PASSTHRU_H diff --git a/src/plugins/canbus/passthrucan/main.cpp b/src/plugins/canbus/passthrucan/main.cpp index 5017597..fe166fe 100644 --- a/src/plugins/canbus/passthrucan/main.cpp +++ b/src/plugins/canbus/passthrucan/main.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Ford Motor Company. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Ford Motor Company. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "passthrucanbackend.h" @@ -42,17 +9,17 @@ QT_BEGIN_NAMESPACE -class PassThruCanBusPlugin : public QObject, public QCanBusFactoryV2 +class PassThruCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") - Q_INTERFACES(QCanBusFactoryV2) + Q_INTERFACES(QCanBusFactory) public: PassThruCanBusPlugin() { qRegisterMetaType<QCanBusDevice::CanBusError>(); - qRegisterMetaType<QVector<QCanBusFrame>>(); + qRegisterMetaType<QList<QCanBusFrame>>(); } QList<QCanBusDeviceInfo> availableDevices(QString *) const override diff --git a/src/plugins/canbus/passthrucan/passthrucan.pro b/src/plugins/canbus/passthrucan/passthrucan.pro deleted file mode 100644 index cb9bdc5..0000000 --- a/src/plugins/canbus/passthrucan/passthrucan.pro +++ /dev/null @@ -1,20 +0,0 @@ -QT = serialbus - -TARGET = qtpassthrucanbus - -SOURCES += \ - j2534passthru.cpp \ - main.cpp \ - passthrucanio.cpp \ - passthrucanbackend.cpp - -HEADERS += \ - j2534passthru.h \ - passthrucanio.h \ - passthrucanbackend.h - -DISTFILES = plugin.json - -PLUGIN_TYPE = canbus -PLUGIN_CLASS_NAME = PassThruCanBusPlugin -load(qt_plugin) diff --git a/src/plugins/canbus/passthrucan/passthrucanbackend.cpp b/src/plugins/canbus/passthrucan/passthrucanbackend.cpp index 2c18160..940913d 100644 --- a/src/plugins/canbus/passthrucan/passthrucanbackend.cpp +++ b/src/plugins/canbus/passthrucan/passthrucanbackend.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Ford Motor Company. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Ford Motor Company. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "passthrucanbackend.h" #include "passthrucanio.h" @@ -130,7 +97,7 @@ PassThruCanBackend::~PassThruCanBackend() m_canIO->deleteLater(); } -void PassThruCanBackend::setConfigurationParameter(int key, const QVariant &value) +void PassThruCanBackend::setConfigurationParameter(ConfigurationKey key, const QVariant &value) { QCanBusDevice::setConfigurationParameter(key, value); @@ -177,14 +144,18 @@ QList<QCanBusDeviceInfo> PassThruCanBackend::interfaces() const QString name = canAdapterName(entries); if (!name.isEmpty()) - list.append(createDeviceInfo(name)); - + list.append(createDeviceInfo(QStringLiteral("passthrucan"), name, false, false)); entries.endGroup(); } #endif return list; } +QCanBusDeviceInfo PassThruCanBackend::deviceInfo() const +{ + return createDeviceInfo(QStringLiteral("passthrucan"), m_deviceName, false, false); +} + bool PassThruCanBackend::open() { if (Q_UNLIKELY(state() != ConnectingState)) { @@ -200,7 +171,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()) { @@ -215,10 +186,9 @@ bool PassThruCanBackend::open() } m_ioThread.start(); - return QMetaObject::invokeMethod(m_canIO, "open", Qt::QueuedConnection, - Q_ARG(QString, library), - Q_ARG(QByteArray, subDev), - Q_ARG(uint, bitRate)); + return QMetaObject::invokeMethod(m_canIO, [this, library, subDev, bitRate] { + m_canIO->open(library, subDev, bitRate); + }, Qt::QueuedConnection); } void PassThruCanBackend::close() @@ -227,7 +197,7 @@ void PassThruCanBackend::close() qCCritical(QT_CANBUS_PLUGINS_PASSTHRU, "Unexpected state on close"); return; } - QMetaObject::invokeMethod(m_canIO, "close", Qt::QueuedConnection); + QMetaObject::invokeMethod(m_canIO, &PassThruCanIO::close, Qt::QueuedConnection); } void PassThruCanBackend::ackOpenFinished(bool success) @@ -250,7 +220,7 @@ void PassThruCanBackend::ackOpenFinished(bool success) } applyConfig(RawFilterKey, filters); - QMetaObject::invokeMethod(m_canIO, "listen", Qt::QueuedConnection); + QMetaObject::invokeMethod(m_canIO, &PassThruCanIO::listen, Qt::QueuedConnection); setState(ConnectedState); } else { @@ -266,8 +236,9 @@ void PassThruCanBackend::ackCloseFinished() setState(UnconnectedState); } -void PassThruCanBackend::applyConfig(int key, const QVariant &value) +void PassThruCanBackend::applyConfig(QCanBusDevice::ConfigurationKey key, const QVariant &value) { - QMetaObject::invokeMethod(m_canIO, "applyConfig", Qt::QueuedConnection, - Q_ARG(int, key), Q_ARG(QVariant, value)); + QMetaObject::invokeMethod(m_canIO, + [this, key, value] { m_canIO->applyConfig(key, value); }, + Qt::QueuedConnection); } diff --git a/src/plugins/canbus/passthrucan/passthrucanbackend.h b/src/plugins/canbus/passthrucan/passthrucanbackend.h index 864d1b4..7f78036 100644 --- a/src/plugins/canbus/passthrucan/passthrucanbackend.h +++ b/src/plugins/canbus/passthrucan/passthrucanbackend.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Ford Motor Company. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Ford Motor Company. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef PASSTHRUCAN_PASSTHRUCANBACKEND_H #define PASSTHRUCAN_PASSTHRUCANBACKEND_H @@ -40,9 +7,9 @@ #include <QtSerialBus/qcanbusdevice.h> #include <QtSerialBus/qcanbusframe.h> +#include <QList> #include <QString> #include <QThread> -#include <QVector> QT_BEGIN_NAMESPACE @@ -56,11 +23,12 @@ public: explicit PassThruCanBackend(const QString &name, QObject *parent = nullptr); virtual ~PassThruCanBackend(); - void setConfigurationParameter(int key, const QVariant &value) override; + void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override; bool writeFrame(const QCanBusFrame &frame) override; QString interpretErrorFrame(const QCanBusFrame &errorFrame) override; static QList<QCanBusDeviceInfo> interfaces(); + QCanBusDeviceInfo deviceInfo() const override; protected: bool open() override; @@ -69,7 +37,7 @@ protected: private: void ackOpenFinished(bool success); void ackCloseFinished(); - void applyConfig(int key, const QVariant &value); + void applyConfig(QCanBusDevice::ConfigurationKey key, const QVariant &value); QString m_deviceName; QThread m_ioThread; @@ -79,6 +47,6 @@ private: QT_END_NAMESPACE Q_DECLARE_METATYPE(QCanBusDevice::CanBusError) -Q_DECLARE_METATYPE(QVector<QCanBusFrame>) +Q_DECLARE_METATYPE(QList<QCanBusFrame>) #endif // PASSTHRUCAN_PASSTHRUCANBACKEND_H diff --git a/src/plugins/canbus/passthrucan/passthrucanio.cpp b/src/plugins/canbus/passthrucan/passthrucanio.cpp index dc3d2c7..4482aa1 100644 --- a/src/plugins/canbus/passthrucan/passthrucanio.cpp +++ b/src/plugins/canbus/passthrucan/passthrucanio.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Ford Motor Company. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Ford Motor Company. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "passthrucanio.h" @@ -106,7 +73,7 @@ void PassThruCanIO::close() emit closeFinished(); } -void PassThruCanIO::applyConfig(int key, const QVariant &value) +void PassThruCanIO::applyConfig(QCanBusDevice::ConfigurationKey key, const QVariant &value) { if (Q_UNLIKELY(!m_passThru)) { qCCritical(QT_CANBUS_PLUGINS_PASSTHRU, "Pass-thru interface not open"); @@ -185,8 +152,8 @@ bool PassThruCanIO::setMessageFilters(const QList<QCanBusDevice::Filter> &filter else mask.setRxStatus({}); - qToBigEndian<quint32>(filter.frameId & filter.frameIdMask, pattern.data()); - qToBigEndian<quint32>(filter.frameIdMask, mask.data()); + qToBigEndian<QCanBusFrame::FrameId>(filter.frameId & filter.frameIdMask, pattern.data()); + qToBigEndian<QCanBusFrame::FrameId>(filter.frameIdMask, mask.data()); if (m_passThru->startMsgFilter(m_channelId, J2534::PassThru::PassFilter, mask, pattern) != J2534::PassThru::NoError) @@ -236,7 +203,7 @@ bool PassThruCanIO::writeMessages() else msg.setTxFlags({}); - qToBigEndian<quint32>(frame.frameId(), msg.data()); + qToBigEndian<QCanBusFrame::FrameId>(frame.frameId(), msg.data()); std::memcpy(msg.data() + 4, payload.data(), payloadSize); } } @@ -287,7 +254,7 @@ void PassThruCanIO::readMessages(bool writePending) return; } const int numFrames = qMin<ulong>(m_ioBuffer.size(), numMsgs); - QVector<QCanBusFrame> frames; + QList<QCanBusFrame> frames; frames.reserve(numFrames); for (int i = 0; i < numFrames; ++i) { @@ -299,7 +266,7 @@ void PassThruCanIO::readMessages(bool writePending) "Message with invalid size %lu received", msg.size()); continue; } - const quint32 msgId = qFromBigEndian<quint32>(msg.data()); + const QCanBusFrame::FrameId msgId = qFromBigEndian<QCanBusFrame::FrameId>(msg.data()); const QByteArray payload (msg.data() + 4, msg.size() - 4); QCanBusFrame frame (msgId, payload); diff --git a/src/plugins/canbus/passthrucan/passthrucanio.h b/src/plugins/canbus/passthrucan/passthrucanio.h index 071174c..a212b59 100644 --- a/src/plugins/canbus/passthrucan/passthrucanio.h +++ b/src/plugins/canbus/passthrucan/passthrucanio.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Ford Motor Company. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Ford Motor Company. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef PASSTHRUCAN_PASSTHRUCANIO_H #define PASSTHRUCAN_PASSTHRUCANIO_H @@ -48,7 +15,6 @@ #include <QString> #include <QTimer> #include <QVariant> -#include <QVector> QT_BEGIN_NAMESPACE @@ -64,7 +30,7 @@ public: Q_INVOKABLE void open(const QString &library, const QByteArray &subDev, uint bitRate); Q_INVOKABLE void close(); - Q_INVOKABLE void applyConfig(int key, const QVariant &value); + Q_INVOKABLE void applyConfig(QCanBusDevice::ConfigurationKey key, const QVariant &value); Q_INVOKABLE void listen(); // Internally locked; safe to call directly from any thread. @@ -72,7 +38,7 @@ public: Q_SIGNALS: void errorOccurred(const QString &description, QCanBusDevice::CanBusError error); - void messagesReceived(QVector<QCanBusFrame> frames); + void messagesReceived(QList<QCanBusFrame> frames); void messagesSent(qint64 count); void openFinished(bool success); void closeFinished(); @@ -88,7 +54,7 @@ private: J2534::PassThru::Handle m_deviceId = 0; J2534::PassThru::Handle m_channelId = 0; QTimer * m_idleNotifier = nullptr; - QVector<J2534::Message> m_ioBuffer; + QList<J2534::Message> m_ioBuffer; QMutex m_writeGuard; QList<QCanBusFrame> m_writeQueue; }; diff --git a/src/plugins/canbus/peakcan/CMakeLists.txt b/src/plugins/canbus/peakcan/CMakeLists.txt new file mode 100644 index 0000000..0e4110c --- /dev/null +++ b/src/plugins/canbus/peakcan/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## PeakCanBusPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(PeakCanBusPlugin + OUTPUT_NAME qtpeakcanbus + PLUGIN_TYPE canbus + SOURCES + main.cpp + peakcan_symbols_p.h + peakcanbackend.cpp peakcanbackend.h peakcanbackend_p.h + LIBRARIES + Qt::Core + Qt::Network + Qt::SerialBus +) diff --git a/src/plugins/canbus/peakcan/main.cpp b/src/plugins/canbus/peakcan/main.cpp index 8ab1b99..bff3261 100644 --- a/src/plugins/canbus/peakcan/main.cpp +++ b/src/plugins/canbus/peakcan/main.cpp @@ -1,39 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "peakcanbackend.h" @@ -47,11 +14,11 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_PEAKCAN, "qt.canbus.plugins.peakcan") -class PeakCanBusPlugin : public QObject, public QCanBusFactoryV2 +class PeakCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") - Q_INTERFACES(QCanBusFactoryV2) + Q_INTERFACES(QCanBusFactory) public: QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override diff --git a/src/plugins/canbus/peakcan/peakcan.pro b/src/plugins/canbus/peakcan/peakcan.pro deleted file mode 100644 index d5b809c..0000000 --- a/src/plugins/canbus/peakcan/peakcan.pro +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = qtpeakcanbus - -QT = core serialbus - -HEADERS += \ - peakcanbackend.h \ - peakcanbackend_p.h \ - peakcan_symbols_p.h - -SOURCES += \ - main.cpp \ - peakcanbackend.cpp - -DISTFILES = plugin.json - -PLUGIN_TYPE = canbus -PLUGIN_CLASS_NAME = PeakCanBusPlugin -load(qt_plugin) diff --git a/src/plugins/canbus/peakcan/peakcan_symbols_p.h b/src/plugins/canbus/peakcan/peakcan_symbols_p.h index 12de76f..bf786a3 100644 --- a/src/plugins/canbus/peakcan/peakcan_symbols_p.h +++ b/src/plugins/canbus/peakcan/peakcan_symbols_p.h @@ -1,39 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// 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. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef PEAKCAN_SYMBOLS_P_H #define PEAKCAN_SYMBOLS_P_H @@ -168,7 +136,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 +165,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 +195,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 @@ -267,15 +241,8 @@ #define PCAN_TYPE_DNG_SJA_EPP 0x06U // PCAN-Dongle EPP SJA1000 // Type definitions -#ifdef Q_OS_MACOS -#define TPCANLong quint64 -#define TPCANLongToFrameID(a) static_cast<quint32>(a) -#else -#define TPCANLong quint32 -#define TPCANLongToFrameID(a) a -#endif #define TPCANHandle quint16 // Represents a PCAN hardware channel handle -#define TPCANStatus TPCANLong // Represents a PCAN status/error code +#define TPCANStatus quint32 // Represents a PCAN status/error code #define TPCANParameter quint8 // Represents a PCAN parameter to be read or set #define TPCANDevice quint8 // Represents a PCAN device #define TPCANMessageType quint8 // Represents the type of a PCAN message @@ -288,7 +255,7 @@ // Represents a PCAN message typedef struct tagTPCANMsg { - TPCANLong ID; // 11/29-bit message identifier + quint32 ID; // 11/29-bit message identifier TPCANMessageType MSGTYPE; // Type of the message quint8 LEN; // Data Length Code of the message (0..8) quint8 DATA[8]; // Data of the message (DATA[0]..DATA[7]) @@ -298,7 +265,7 @@ typedef struct tagTPCANMsg // Total Microseconds = micros + 1000 * millis + 0xFFFFFFFF * 1000 * millis_overflow typedef struct tagTPCANTimestamp { - TPCANLong millis; // Base-value: milliseconds: 0.. 2^32-1 + quint32 millis; // Base-value: milliseconds: 0.. 2^32-1 quint16 millis_overflow; // Roll-arounds of millis quint16 micros; // Microseconds: 0..999 } TPCANTimestamp; @@ -306,12 +273,24 @@ typedef struct tagTPCANTimestamp // Represents a PCAN message from a FD capable hardware typedef struct tagTPCANMsgFD { - TPCANLong ID; // 11/29-bit message identifier + quint32 ID; // 11/29-bit message identifier TPCANMessageType MSGTYPE; // Type of the message quint8 DLC; // Data Length Code of the message (0..15) 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; @@ -321,7 +300,7 @@ typedef struct tagTPCANMsgFD if (!symbolName) \ return false; -GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_Initialize, TPCANHandle, TPCANBaudrate, TPCANType, TPCANLong, quint16) +GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_Initialize, TPCANHandle, TPCANBaudrate, TPCANType, quint32, quint16) GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_InitializeFD, TPCANHandle, TPCANBitrateFD) GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_Uninitialize, TPCANHandle) GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_Reset, TPCANHandle) @@ -330,9 +309,9 @@ GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_Read, TPCANHandle, TPCANMsg *, TPCANTi GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_ReadFD, TPCANHandle, TPCANMsgFD *, TPCANTimestampFD *) GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_Write, TPCANHandle, TPCANMsg *) GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_WriteFD, TPCANHandle, TPCANMsgFD *) -GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_FilterMessages, TPCANHandle, TPCANLong, TPCANLong, TPCANMode) -GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_GetValue, TPCANHandle, TPCANParameter, void *, TPCANLong) -GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_SetValue, TPCANHandle, TPCANParameter, void *, TPCANLong) +GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_FilterMessages, TPCANHandle, quint32, quint32, TPCANMode) +GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_GetValue, TPCANHandle, TPCANParameter, void *, quint32) +GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_SetValue, TPCANHandle, TPCANParameter, void *, quint32) GENERATE_SYMBOL_VARIABLE(TPCANStatus, CAN_GetErrorText, TPCANStatus, quint16, char *) inline bool resolvePeakCanSymbols(QLibrary *pcanLibrary) diff --git a/src/plugins/canbus/peakcan/peakcanbackend.cpp b/src/plugins/canbus/peakcan/peakcanbackend.cpp index 5a17b22..6d8ce94 100644 --- a/src/plugins/canbus/peakcan/peakcanbackend.cpp +++ b/src/plugins/canbus/peakcan/peakcanbackend.cpp @@ -1,39 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// 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. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "peakcanbackend.h" #include "peakcanbackend_p.h" @@ -46,6 +14,7 @@ #include <QtCore/qloggingcategory.h> #include <algorithm> +#include <vector> #ifdef Q_OS_WIN32 # include <QtCore/qwineventnotifier.h> @@ -64,7 +33,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 +42,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 +95,7 @@ static const PcanChannel pcanChannels[] = { { "none", PCAN_NONEBUS } }; -QList<QCanBusDeviceInfo> PeakCanBackend::interfaces() +QList<QCanBusDeviceInfo> PeakCanBackend::interfacesByChannelCondition(Availability available) { QList<QCanBusDeviceInfo> result; @@ -126,7 +104,7 @@ QList<QCanBusDeviceInfo> PeakCanBackend::interfaces() const TPCANHandle index = pcanChannels[i].index; const TPCANStatus stat = ::CAN_GetValue(index, PCAN_CHANNEL_CONDITION, &value, sizeof(value)); - if ((stat == PCAN_ERROR_OK) && (value & PCAN_CHANNEL_AVAILABLE)) { + if ((stat == PCAN_ERROR_OK) && (value & uint(available))) { const TPCANStatus fdStat = ::CAN_GetValue(index, PCAN_CHANNEL_FEATURES, &value, sizeof(value)); const bool isFd = (fdStat == PCAN_ERROR_OK) && (value & FEATURE_FD_CAPABLE); @@ -143,15 +121,115 @@ QList<QCanBusDeviceInfo> PeakCanBackend::interfaces() if (chnStat != PCAN_ERROR_OK) channel = 0; - result.append(std::move(createDeviceInfo(QLatin1String(pcanChannels[i].name), - QString(), QLatin1String(description), - channel, false, isFd))); + 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(QCanBusDevice::createDeviceInfo(QStringLiteral("peakcan"), + QLatin1String(pcanChannels[i].name), + QString(), QLatin1String(description), + alias, channel, false, isFd)); } } return result; } +static QString pcanChannelNameForIndex(uint index) +{ + const auto pcanChannel = std::find_if(std::begin(pcanChannels), std::end(pcanChannels), + [index](PcanChannel channel) { + return channel.index == index; + }); + if (Q_LIKELY(pcanChannel != std::end(pcanChannels))) + return pcanChannel->name; + + qWarning("%s: Cannot get channel name for index %u.", Q_FUNC_INFO, index); + return QStringLiteral("none"); +} + +QList<QCanBusDeviceInfo> PeakCanBackend::interfacesByAttachedChannels(Availability available, 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(), + quint32(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 & uint(available)) { + const QString name = pcanChannelNameForIndex(info.channel_handle); + 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(createDeviceInfo(QStringLiteral("peakcan"), name, QString(), + description, alias, + channel, false, isCanFd)); + } + } + + return result; +} + +QList<QCanBusDeviceInfo> PeakCanBackend::attachedInterfaces(Availability available) +{ +#ifdef Q_OS_WIN + bool ok = false; + QList<QCanBusDeviceInfo> attachedChannelsResult = interfacesByAttachedChannels(available, &ok); + if (ok) + return attachedChannelsResult; +#endif + + QList<QCanBusDeviceInfo> result = interfacesByChannelCondition(available); + return result; +} + +QList<QCanBusDeviceInfo> PeakCanBackend::interfaces() +{ + return attachedInterfaces(Availability::Available); +} + +QCanBusDeviceInfo PeakCanBackend::deviceInfo() const +{ + const uint index = d_ptr->channelIndex; + const QString name = pcanChannelNameForIndex(index); + const QList<QCanBusDeviceInfo> availableDevices = attachedInterfaces(Availability::Occupied); + + const auto deviceInfo = std::find_if(availableDevices.constBegin(), + availableDevices.constEnd(), + [name](const QCanBusDeviceInfo &info) { + return name == info.name(); + }); + + if (Q_LIKELY(deviceInfo != availableDevices.constEnd())) + return *deviceInfo; + + qWarning("%s: Cannot get device info for index %u.", Q_FUNC_INFO, index); + return QCanBusDevice::deviceInfo(); +} + #if defined(Q_OS_WIN32) class PeakCanReadNotifier : public QWinEventNotifier { @@ -162,16 +240,10 @@ public: , dptr(d) { setHandle(dptr->readHandle); - } -protected: - bool event(QEvent *e) override - { - if (e->type() == QEvent::WinEventAct) { + connect(this, &QWinEventNotifier::activated, this, [this]() { dptr->startRead(); - return true; - } - return QWinEventNotifier::event(e); + }); } private: @@ -344,7 +416,7 @@ bool PeakCanBackendPrivate::open() if (readHandle == INVALID_HANDLE_VALUE) { readHandle = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); if (Q_UNLIKELY(!readHandle)) { - const QString errorString = qt_error_string(::GetLastError()); + const QString errorString = qt_error_string(int(::GetLastError())); qCCritical(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot create receive event handler: %ls", qUtf16Printable(errorString)); q->setError(errorString, QCanBusDevice::ConnectionError); @@ -404,7 +476,7 @@ void PeakCanBackendPrivate::close() #if defined(Q_OS_WIN32) if (readHandle && (readHandle != INVALID_HANDLE_VALUE)) { - const QString errorString = qt_error_string(::GetLastError()); + const QString errorString = qt_error_string(int(::GetLastError())); if (Q_UNLIKELY(!::CloseHandle(readHandle))) { qCCritical(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot close read handle: %ls", qUtf16Printable(errorString)); @@ -419,7 +491,8 @@ void PeakCanBackendPrivate::close() isOpen = false; } -bool PeakCanBackendPrivate::setConfigurationParameter(int key, const QVariant &value) +bool PeakCanBackendPrivate::setConfigurationParameter(QCanBusDevice::ConfigurationKey key, + const QVariant &value) { Q_Q(PeakCanBackend); @@ -557,14 +630,13 @@ void PeakCanBackendPrivate::startWrite() const QCanBusFrame frame = q->dequeueOutgoingFrame(); const QByteArray payload = frame.payload(); + const qsizetype payloadSize = payload.size(); TPCANStatus st = PCAN_ERROR_OK; if (isFlexibleDatarateEnabled) { - const int size = payload.size(); - TPCANMsgFD message; - ::memset(&message, 0, sizeof(message)); + TPCANMsgFD message = {}; message.ID = frame.frameId(); - message.DLC = sizeToDlc(size); + message.DLC = sizeToDlc(payloadSize); message.MSGTYPE = frame.hasExtendedFrameFormat() ? PCAN_MESSAGE_EXTENDED : PCAN_MESSAGE_STANDARD; @@ -576,25 +648,23 @@ void PeakCanBackendPrivate::startWrite() if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) message.MSGTYPE |= PCAN_MESSAGE_RTR; // we do not care about the payload else - ::memcpy(message.DATA, payload.constData(), sizeof(message.DATA)); + ::memcpy(message.DATA, payload.constData(), payloadSize); st = ::CAN_WriteFD(channelIndex, &message); } else if (frame.hasFlexibleDataRateFormat()) { const char errorString[] = "Cannot send CAN FD frame format as CAN FD is not enabled."; qCWarning(QT_CANBUS_PLUGINS_PEAKCAN(), errorString); q->setError(PeakCanBackend::tr(errorString), QCanBusDevice::WriteError); } else { - TPCANMsg message; - ::memset(&message, 0, sizeof(message)); - + TPCANMsg message = {}; message.ID = frame.frameId(); - message.LEN = static_cast<quint8>(payload.size()); + message.LEN = static_cast<quint8>(payloadSize); message.MSGTYPE = frame.hasExtendedFrameFormat() ? PCAN_MESSAGE_EXTENDED : PCAN_MESSAGE_STANDARD; if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) message.MSGTYPE |= PCAN_MESSAGE_RTR; // we do not care about the payload else - ::memcpy(message.DATA, payload.constData(), sizeof(message.DATA)); + ::memcpy(message.DATA, payload.constData(), payloadSize); st = ::CAN_Write(channelIndex, &message); } @@ -615,14 +685,12 @@ void PeakCanBackendPrivate::startRead() { Q_Q(PeakCanBackend); - QVector<QCanBusFrame> newFrames; + QList<QCanBusFrame> newFrames; for (;;) { if (isFlexibleDatarateEnabled) { - TPCANMsgFD message; - ::memset(&message, 0, sizeof(message)); - TPCANTimestampFD timestamp; - ::memset(×tamp, 0, sizeof(timestamp)); + TPCANMsgFD message = {}; + TPCANTimestampFD timestamp = {}; const TPCANStatus st = ::CAN_ReadFD(channelIndex, &message, ×tamp); if (st != PCAN_ERROR_OK) { @@ -637,8 +705,7 @@ void PeakCanBackendPrivate::startRead() continue; const int size = dlcToSize(static_cast<CanFrameDlc>(message.DLC)); - QCanBusFrame frame(TPCANLongToFrameID(message.ID), - QByteArray(reinterpret_cast<const char *>(message.DATA), size)); + QCanBusFrame frame(message.ID, QByteArray(reinterpret_cast<const char *>(message.DATA), size)); frame.setTimeStamp(QCanBusFrame::TimeStamp::fromMicroSeconds(static_cast<qint64>(timestamp))); frame.setExtendedFrameFormat(message.MSGTYPE & PCAN_MESSAGE_EXTENDED); frame.setFrameType((message.MSGTYPE & PCAN_MESSAGE_RTR) @@ -649,10 +716,8 @@ void PeakCanBackendPrivate::startRead() newFrames.append(std::move(frame)); } else { - TPCANMsg message; - ::memset(&message, 0, sizeof(message)); - TPCANTimestamp timestamp; - ::memset(×tamp, 0, sizeof(timestamp)); + TPCANMsg message = {}; + TPCANTimestamp timestamp = {}; const TPCANStatus st = ::CAN_Read(channelIndex, &message, ×tamp); if (st != PCAN_ERROR_OK) { @@ -667,9 +732,8 @@ void PeakCanBackendPrivate::startRead() continue; const int size = static_cast<int>(message.LEN); - QCanBusFrame frame(TPCANLongToFrameID(message.ID), - QByteArray(reinterpret_cast<const char *>(message.DATA), size)); - const quint64 millis = timestamp.millis + Q_UINT64_C(0xFFFFFFFF) * timestamp.millis_overflow; + QCanBusFrame frame(message.ID, QByteArray(reinterpret_cast<const char *>(message.DATA), size)); + const quint64 millis = timestamp.millis + Q_UINT64_C(0x100000000) * timestamp.millis_overflow; const quint64 micros = Q_UINT64_C(1000) * millis + timestamp.micros; frame.setTimeStamp(QCanBusFrame::TimeStamp::fromMicroSeconds(static_cast<qint64>(micros))); frame.setExtendedFrameFormat(message.MSGTYPE & PCAN_MESSAGE_EXTENDED); @@ -717,12 +781,6 @@ PeakCanBackend::PeakCanBackend(const QString &name, QObject *parent) d->setupChannel(name.toLatin1()); d->setupDefaultConfigurations(); - - std::function<void()> f = std::bind(&PeakCanBackend::resetController, this); - setResetControllerFunction(f); - - std::function<CanBusStatus()> g = std::bind(&PeakCanBackend::busStatus, this); - setCanBusStatusGetter(g); } PeakCanBackend::~PeakCanBackend() @@ -746,7 +804,7 @@ bool PeakCanBackend::open() // Apply all stored configurations except bitrate, because // the bitrate cannot be changed after opening the device const auto keys = configurationKeys(); - for (int key : keys) { + for (ConfigurationKey key : keys) { if (key == QCanBusDevice::BitRateKey || key == QCanBusDevice::DataBitRateKey) continue; const QVariant param = configurationParameter(key); @@ -771,7 +829,7 @@ void PeakCanBackend::close() setState(QCanBusDevice::UnconnectedState); } -void PeakCanBackend::setConfigurationParameter(int key, const QVariant &value) +void PeakCanBackend::setConfigurationParameter(ConfigurationKey key, const QVariant &value) { Q_D(PeakCanBackend); @@ -820,7 +878,12 @@ void PeakCanBackend::resetController() open(); } -QCanBusDevice::CanBusStatus PeakCanBackend::busStatus() const +bool PeakCanBackend::hasBusStatus() const +{ + return true; +} + +QCanBusDevice::CanBusStatus PeakCanBackend::busStatus() { const TPCANStatus status = ::CAN_GetStatus(d_ptr->channelIndex); diff --git a/src/plugins/canbus/peakcan/peakcanbackend.h b/src/plugins/canbus/peakcan/peakcanbackend.h index a9e108e..7e3acd4 100644 --- a/src/plugins/canbus/peakcan/peakcanbackend.h +++ b/src/plugins/canbus/peakcan/peakcanbackend.h @@ -1,50 +1,16 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef PEAKCANBACKEND_H #define PEAKCANBACKEND_H -#include <QtSerialBus/qcanbusframe.h> #include <QtSerialBus/qcanbusdevice.h> #include <QtSerialBus/qcanbusdeviceinfo.h> +#include <QtSerialBus/qcanbusframe.h> -#include <QtCore/qvariant.h> -#include <QtCore/qvector.h> #include <QtCore/qlist.h> +#include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -62,7 +28,7 @@ public: bool open() override; void close() override; - void setConfigurationParameter(int key, const QVariant &value) override; + void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override; bool writeFrame(const QCanBusFrame &newData) override; @@ -71,9 +37,19 @@ public: static bool canCreate(QString *errorReason); static QList<QCanBusDeviceInfo> interfaces(); + void resetController() override; + bool hasBusStatus() const override; + CanBusStatus busStatus() override; + QCanBusDeviceInfo deviceInfo() const override; + private: - void resetController(); - CanBusStatus busStatus() const; + enum class Availability { + Available = 1U, // matches PCAN_CHANNEL_AVAILABLE + Occupied = 2U // matches PCAN_CHANNEL_OCCUPIED + }; + static QList<QCanBusDeviceInfo> interfacesByChannelCondition(Availability available); + static QList<QCanBusDeviceInfo> interfacesByAttachedChannels(Availability available, bool *ok); + static QList<QCanBusDeviceInfo> attachedInterfaces(Availability available); PeakCanBackendPrivate * const d_ptr; }; diff --git a/src/plugins/canbus/peakcan/peakcanbackend_p.h b/src/plugins/canbus/peakcan/peakcanbackend_p.h index 96d7ad3..866a39d 100644 --- a/src/plugins/canbus/peakcan/peakcanbackend_p.h +++ b/src/plugins/canbus/peakcan/peakcanbackend_p.h @@ -1,39 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef PEAKCANBACKEND_P_H #define PEAKCANBACKEND_P_H @@ -72,7 +39,7 @@ public: bool open(); void close(); - bool setConfigurationParameter(int key, const QVariant &value); + bool setConfigurationParameter(QCanBusDevice::ConfigurationKey key, const QVariant &value); void setupChannel(const QByteArray &interfaceName); void setupDefaultConfigurations(); QString systemErrorString(TPCANStatus errorCode); diff --git a/src/plugins/canbus/socketcan/CMakeLists.txt b/src/plugins/canbus/socketcan/CMakeLists.txt new file mode 100644 index 0000000..0ec3b64 --- /dev/null +++ b/src/plugins/canbus/socketcan/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## SocketCanBusPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(SocketCanBusPlugin + OUTPUT_NAME qtsocketcanbus + PLUGIN_TYPE canbus + SOURCES + libsocketcan.cpp libsocketcan.h + main.cpp + socketcanbackend.cpp socketcanbackend.h + LIBRARIES + Qt::Core + Qt::Network + Qt::SerialBus +) diff --git a/src/plugins/canbus/socketcan/libsocketcan.cpp b/src/plugins/canbus/socketcan/libsocketcan.cpp index c6144db..c469604 100644 --- a/src/plugins/canbus/socketcan/libsocketcan.cpp +++ b/src/plugins/canbus/socketcan/libsocketcan.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "libsocketcan.h" @@ -87,10 +54,14 @@ LibSocketCan::LibSocketCan(QString *errorString) { #if QT_CONFIG(library) auto resolveSymbols = [](QLibrary *library) { + const QString libName = QStringLiteral("socketcan"); if (!library->isLoaded()) { - library->setFileName(QStringLiteral("socketcan")); - if (!library->load()) - return false; + library->setFileName(libName); + if (!library->load()) { + library->setFileNameAndVersion(libName, 2); + if (!library->load()) + return false; + } } RESOLVE_SYMBOL(can_do_start); diff --git a/src/plugins/canbus/socketcan/libsocketcan.h b/src/plugins/canbus/socketcan/libsocketcan.h index b77afa1..1fa4175 100644 --- a/src/plugins/canbus/socketcan/libsocketcan.h +++ b/src/plugins/canbus/socketcan/libsocketcan.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef LIBSOCKETCAN_H #define LIBSOCKETCAN_H diff --git a/src/plugins/canbus/socketcan/main.cpp b/src/plugins/canbus/socketcan/main.cpp index 328db97..e833f6d 100644 --- a/src/plugins/canbus/socketcan/main.cpp +++ b/src/plugins/canbus/socketcan/main.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "socketcanbackend.h" @@ -47,11 +14,11 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_SOCKETCAN, "qt.canbus.plugins.socketcan") //! [SocketCanFactory] -class SocketCanBusPlugin : public QObject, public QCanBusFactoryV2 +class SocketCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") - Q_INTERFACES(QCanBusFactoryV2) + Q_INTERFACES(QCanBusFactory) public: QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override diff --git a/src/plugins/canbus/socketcan/socketcan.pro b/src/plugins/canbus/socketcan/socketcan.pro deleted file mode 100644 index cd731fd..0000000 --- a/src/plugins/canbus/socketcan/socketcan.pro +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = qtsocketcanbus - -QT = core serialbus - -HEADERS += \ - libsocketcan.h \ - socketcanbackend.h - -SOURCES += \ - libsocketcan.cpp \ - main.cpp \ - socketcanbackend.cpp - -DISTFILES = plugin.json - -PLUGIN_TYPE = canbus -PLUGIN_CLASS_NAME = SocketCanBusPlugin -load(qt_plugin) diff --git a/src/plugins/canbus/socketcan/socketcanbackend.cpp b/src/plugins/canbus/socketcan/socketcanbackend.cpp index 2ed1310..c89b9a4 100644 --- a/src/plugins/canbus/socketcan/socketcanbackend.cpp +++ b/src/plugins/canbus/socketcan/socketcanbackend.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "socketcanbackend.h" @@ -56,30 +23,6 @@ #include <sys/ioctl.h> #include <sys/time.h> -#ifndef CANFD_MTU -// CAN FD support was added by Linux kernel 3.6 -// For prior kernels we redefine the missing defines here -// they are taken from linux/can/raw.h & linux/can.h - -enum { - CAN_RAW_FD_FRAMES = 5 -}; - -#define CAN_MAX_DLEN 8 -#define CANFD_MAX_DLEN 64 -struct canfd_frame { - canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ - __u8 len; /* frame payload length in byte */ - __u8 flags; /* additional flags for CAN FD */ - __u8 __res0; /* reserved / padding */ - __u8 __res1; /* reserved / padding */ - __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8))); -}; -#define CAN_MTU (sizeof(struct can_frame)) -#define CANFD_MTU (sizeof(struct canfd_frame)) - -#endif - #ifndef CANFD_BRS # define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */ #endif @@ -151,6 +94,18 @@ static int deviceChannel(const QString &canDevice) return content.toInt(nullptr, 0); } +QCanBusDeviceInfo SocketCanBackend::socketCanDeviceInfo(const QString &deviceName) +{ + const QString serial; // exists for code readability purposes only + const QString alias; // exists for code readability purposes only + const QString description = deviceDescription(deviceName); + const int channel = deviceChannel(deviceName); + return createDeviceInfo(QStringLiteral("socketcan"), deviceName, + serial, description, + alias, channel, isVirtual(deviceName), + isFlexibleDataRateCapable(deviceName)); +} + QList<QCanBusDeviceInfo> SocketCanBackend::interfaces() { QList<QCanBusDeviceInfo> result; @@ -167,12 +122,7 @@ QList<QCanBusDeviceInfo> SocketCanBackend::interfaces() if (!(flags(deviceName) & DeviceIsActive)) continue; - const QString serial; - const QString description = deviceDescription(deviceName); - const int channel = deviceChannel(deviceName); - result.append(std::move(createDeviceInfo(deviceName, serial, description, - channel, isVirtual(deviceName), - isFlexibleDataRateCapable(deviceName)))); + result.append(socketCanDeviceInfo(deviceName)); } std::sort(result.begin(), result.end(), @@ -183,6 +133,11 @@ QList<QCanBusDeviceInfo> SocketCanBackend::interfaces() return result; } +QCanBusDeviceInfo SocketCanBackend::deviceInfo() const +{ + return socketCanDeviceInfo(canSocketName); +} + SocketCanBackend::SocketCanBackend(const QString &name) : canSocketName(name) { @@ -195,16 +150,6 @@ SocketCanBackend::SocketCanBackend(const QString &name) : } resetConfigurations(); - - std::function<void()> f = std::bind(&SocketCanBackend::resetController, this); - setResetControllerFunction(f); - - if (hasBusStatus()) { - // Only register busStatus when libsocketcan is available - // QCanBusDevice::hasBusStatus() will return false otherwise - std::function<CanBusStatus()> g = std::bind(&SocketCanBackend::busStatus, this); - setCanBusStatusGetter(g); - } } SocketCanBackend::~SocketCanBackend() @@ -248,7 +193,7 @@ void SocketCanBackend::close() setState(QCanBusDevice::UnconnectedState); } -bool SocketCanBackend::applyConfigurationParameter(int key, const QVariant &value) +bool SocketCanBackend::applyConfigurationParameter(ConfigurationKey key, const QVariant &value) { bool success = false; @@ -308,7 +253,7 @@ bool SocketCanBackend::applyConfigurationParameter(int key, const QVariant &valu break; } - QVector<can_filter> filters; + QList<can_filter> filters; filters.resize(filterList.size()); for (int i = 0; i < filterList.size(); i++) { const QCanBusDevice::Filter f = filterList.at(i); @@ -373,11 +318,11 @@ bool SocketCanBackend::applyConfigurationParameter(int key, const QVariant &valu case QCanBusDevice::BitRateKey: { const quint32 bitRate = value.toUInt(); - libSocketCan->setBitrate(canSocketName, bitRate); + success = libSocketCan->setBitrate(canSocketName, bitRate); break; } default: - setError(tr("SocketCanBackend: No such configuration as %1 in SocketCanBackend").arg(key), + setError(tr("Unsupported configuration key: %1").arg(key), QCanBusDevice::CanBusError::ConfigurationError); break; } @@ -425,7 +370,7 @@ bool SocketCanBackend::connectSocket() //apply all stored configurations const auto keys = configurationKeys(); - for (int key : keys) { + for (ConfigurationKey key : keys) { const QVariant param = configurationParameter(key); bool success = applyConfigurationParameter(key, param); if (Q_UNLIKELY(!success)) { @@ -437,7 +382,7 @@ bool SocketCanBackend::connectSocket() return true; } -void SocketCanBackend::setConfigurationParameter(int key, const QVariant &value) +void SocketCanBackend::setConfigurationParameter(ConfigurationKey key, const QVariant &value) { if (key == QCanBusDevice::RawFilterKey) { //verify valid/supported filters @@ -481,7 +426,7 @@ void SocketCanBackend::setConfigurationParameter(int key, const QVariant &value) QCanBusDevice::setConfigurationParameter(key, value); - // we need to check CAN FD option a lot -> cache it and avoid QVector lookup + // we need to check CAN FD option a lot -> cache it and avoid QList lookup if (key == QCanBusDevice::CanFdKey) canFdOptionEnabled = value.toBool(); } @@ -516,8 +461,7 @@ bool SocketCanBackend::writeFrame(const QCanBusFrame &newData) qint64 bytesWritten = 0; if (newData.hasFlexibleDataRateFormat()) { - canfd_frame frame; - ::memset(&frame, 0, sizeof(frame)); + canfd_frame frame = {}; frame.len = newData.payload().size(); frame.can_id = canId; frame.flags = newData.hasBitrateSwitch() ? CANFD_BRS : 0; @@ -526,8 +470,7 @@ bool SocketCanBackend::writeFrame(const QCanBusFrame &newData) bytesWritten = ::write(canSocket, &frame, sizeof(frame)); } else { - can_frame frame; - ::memset(&frame, 0, sizeof(frame)); + can_frame frame = {}; frame.can_dlc = newData.payload().size(); frame.can_id = canId; ::memcpy(frame.data, newData.payload().constData(), frame.can_dlc); @@ -556,7 +499,7 @@ QString SocketCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame) QString errorMsg; if (errorFrame.error() & QCanBusFrame::TransmissionTimeoutError) - errorMsg += QStringLiteral("TX timout\n"); + errorMsg += QStringLiteral("TX timeout\n"); if (errorFrame.error() & QCanBusFrame::MissingAcknowledgmentError) errorMsg += QStringLiteral("Received no ACK on transmission\n"); @@ -711,10 +654,10 @@ QString SocketCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame) void SocketCanBackend::readSocket() { - QVector<QCanBusFrame> newFrames; + QList<QCanBusFrame> newFrames; for (;;) { - ::memset(&m_frame, 0, sizeof(m_frame)); + m_frame = {}; m_iov.iov_len = sizeof(m_frame); m_msg.msg_namelen = sizeof(m_addr); m_msg.msg_controllen = sizeof(m_ctrlmsg); @@ -734,11 +677,11 @@ void SocketCanBackend::readSocket() continue; } - struct timeval timeStamp; + struct timeval timeStamp = {}; if (Q_UNLIKELY(ioctl(canSocket, SIOCGSTAMP, &timeStamp) < 0)) { setError(qt_error_string(errno), QCanBusDevice::CanBusError::ReadError); - ::memset(&timeStamp, 0, sizeof(timeStamp)); + timeStamp = {}; } const QCanBusFrame::TimeStamp stamp(timeStamp.tv_sec, timeStamp.tv_usec); @@ -778,10 +721,13 @@ void SocketCanBackend::resetController() bool SocketCanBackend::hasBusStatus() const { + if (isVirtual(canSocketName.toLatin1())) + return false; + return libSocketCan->hasBusStatus(); } -QCanBusDevice::CanBusStatus SocketCanBackend::busStatus() const +QCanBusDevice::CanBusStatus SocketCanBackend::busStatus() { return libSocketCan->busStatus(canSocketName); } diff --git a/src/plugins/canbus/socketcan/socketcanbackend.h b/src/plugins/canbus/socketcan/socketcanbackend.h index 0497244..89aa281 100644 --- a/src/plugins/canbus/socketcan/socketcanbackend.h +++ b/src/plugins/canbus/socketcan/socketcanbackend.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef SOCKETCANBACKEND_H #define SOCKETCANBACKEND_H @@ -54,6 +21,30 @@ #include <memory> +#ifndef CANFD_MTU +// CAN FD support was added by Linux kernel 3.6 +// For prior kernels we redefine the missing defines here +// they are taken from linux/can/raw.h & linux/can.h + +enum { + CAN_RAW_FD_FRAMES = 5 +}; + +#define CAN_MAX_DLEN 8 +#define CANFD_MAX_DLEN 64 +struct canfd_frame { + canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ + __u8 len; /* frame payload length in byte */ + __u8 flags; /* additional flags for CAN FD */ + __u8 __res0; /* reserved / padding */ + __u8 __res1; /* reserved / padding */ + __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8))); +}; +#define CAN_MTU (sizeof(struct can_frame)) +#define CANFD_MTU (sizeof(struct canfd_frame)) + +#endif + QT_BEGIN_NAMESPACE class LibSocketCan; @@ -68,24 +59,27 @@ public: bool open() override; void close() override; - void setConfigurationParameter(int key, const QVariant &value) override; + void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override; bool writeFrame(const QCanBusFrame &newData) override; QString interpretErrorFrame(const QCanBusFrame &errorFrame) override; + static QCanBusDeviceInfo socketCanDeviceInfo(const QString &deviceName); static QList<QCanBusDeviceInfo> interfaces(); + void resetController() override; + bool hasBusStatus() const override; + CanBusStatus busStatus() override; + QCanBusDeviceInfo deviceInfo() const override; + private Q_SLOTS: void readSocket(); private: void resetConfigurations(); bool connectSocket(); - bool applyConfigurationParameter(int key, const QVariant &value); - void resetController(); - bool hasBusStatus() const; - QCanBusDevice::CanBusStatus busStatus() const; + bool applyConfigurationParameter(ConfigurationKey key, const QVariant &value); int protocol = CAN_RAW; canfd_frame m_frame; diff --git a/src/plugins/canbus/systeccan/CMakeLists.txt b/src/plugins/canbus/systeccan/CMakeLists.txt new file mode 100644 index 0000000..a36ee1c --- /dev/null +++ b/src/plugins/canbus/systeccan/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## SystecCanBusPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(SystecCanBusPlugin + OUTPUT_NAME qtsysteccanbus + PLUGIN_TYPE canbus + SOURCES + main.cpp + systeccan_symbols_p.h + systeccanbackend.cpp systeccanbackend.h systeccanbackend_p.h + LIBRARIES + Qt::Core + Qt::Network + Qt::SerialBus +) diff --git a/src/plugins/canbus/systeccan/main.cpp b/src/plugins/canbus/systeccan/main.cpp index 89377a0..96ce57c 100644 --- a/src/plugins/canbus/systeccan/main.cpp +++ b/src/plugins/canbus/systeccan/main.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "systeccanbackend.h" @@ -46,11 +13,11 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_SYSTECCAN, "qt.canbus.plugins.systeccan") -class SystecCanBusPlugin : public QObject, public QCanBusFactoryV2 +class SystecCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") - Q_INTERFACES(QCanBusFactoryV2) + Q_INTERFACES(QCanBusFactory) public: QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override diff --git a/src/plugins/canbus/systeccan/systeccan.pro b/src/plugins/canbus/systeccan/systeccan.pro deleted file mode 100644 index 3520325..0000000 --- a/src/plugins/canbus/systeccan/systeccan.pro +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = qtsysteccanbus - -QT = core serialbus - -HEADERS += \ - systeccanbackend.h \ - systeccanbackend_p.h \ - systeccan_symbols_p.h - -SOURCES += \ - main.cpp \ - systeccanbackend.cpp - -DISTFILES = plugin.json - -PLUGIN_TYPE = canbus -PLUGIN_CLASS_NAME = SystecCanBusPlugin -load(qt_plugin) diff --git a/src/plugins/canbus/systeccan/systeccan_symbols_p.h b/src/plugins/canbus/systeccan/systeccan_symbols_p.h index 037f994..4fa1a93 100644 --- a/src/plugins/canbus/systeccan/systeccan_symbols_p.h +++ b/src/plugins/canbus/systeccan/systeccan_symbols_p.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef SYSTECCAN_SYMBOLS_P_H #define SYSTECCAN_SYMBOLS_P_H @@ -302,6 +269,8 @@ GENERATE_SYMBOL_VARIABLE(UCANRET, UcanReadCanMsgEx, tUcanHandle, quint8 *, tCanM GENERATE_SYMBOL_VARIABLE(UCANRET, UcanResetCan, tUcanHandle) GENERATE_SYMBOL_VARIABLE(UCANRET, UcanWriteCanMsgEx, tUcanHandle, quint8, tCanMsgStruct *, quint32 *) GENERATE_SYMBOL_VARIABLE(UCANRET, UcanGetStatus, tUcanHandle, tStatusStruct *) +GENERATE_SYMBOL_VARIABLE(UCANRET, UcanGetHardwareInfoEx2, tUcanHandle, tUcanHardwareInfoEx *, + void * /* channelInfo0 */, void * /* channelInfo1 */); inline bool resolveSystecCanSymbols(QLibrary *systecLibrary) { @@ -324,6 +293,7 @@ inline bool resolveSystecCanSymbols(QLibrary *systecLibrary) RESOLVE_SYMBOL(UcanResetCan); RESOLVE_SYMBOL(UcanWriteCanMsgEx); RESOLVE_SYMBOL(UcanGetStatus); + RESOLVE_SYMBOL(UcanGetHardwareInfoEx2); return true; } diff --git a/src/plugins/canbus/systeccan/systeccanbackend.cpp b/src/plugins/canbus/systeccan/systeccanbackend.cpp index a7de557..f14c27b 100644 --- a/src/plugins/canbus/systeccan/systeccanbackend.cpp +++ b/src/plugins/canbus/systeccan/systeccanbackend.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "systeccanbackend.h" #include "systeccanbackend_p.h" @@ -69,7 +36,9 @@ QCanBusDeviceInfo SystecCanBackend::createDeviceInfo(const QString &serialNumber int channelNumber) { const QString name = QString::fromLatin1("can%1.%2").arg(deviceNumber).arg(channelNumber); - return QCanBusDevice::createDeviceInfo(name, serialNumber, description, channelNumber, false, false); + return QCanBusDevice::createDeviceInfo(QStringLiteral("systeccan"), name, + serialNumber, description, + QString(), channelNumber, false, false); } static QString descriptionString(uint productCode) @@ -100,11 +69,11 @@ static void DRV_CALLBACK_TYPE ucanEnumCallback(DWORD index, BOOL isUsed, const QString serialNumber = QString::number(hardwareInfo->m_dwSerialNr); const QString description = descriptionString(hardwareInfo->m_dwProductCode); - result->append(std::move(SystecCanBackend::createDeviceInfo(serialNumber, description, - hardwareInfo->m_bDeviceNr, 0))); + result->append(SystecCanBackend::createDeviceInfo(serialNumber, description, + hardwareInfo->m_bDeviceNr, 0)); if (USBCAN_CHECK_SUPPORT_TWO_CHANNEL(hardwareInfo)) { - result->append(std::move(SystecCanBackend::createDeviceInfo(serialNumber, description, - hardwareInfo->m_bDeviceNr, 1))); + result->append(SystecCanBackend::createDeviceInfo(serialNumber, description, + hardwareInfo->m_bDeviceNr, 1)); } initInfo->m_fTryNext = true; // continue enumerating with next device @@ -202,8 +171,7 @@ bool SystecCanBackendPrivate::open() const int bitrate = q->configurationParameter(QCanBusDevice::BitRateKey).toInt(); const bool receiveOwn = q->configurationParameter(QCanBusDevice::ReceiveOwnKey).toBool(); - tUcanInitCanParam param; - ::memset(¶m, 0, sizeof(param)); + tUcanInitCanParam param = {}; param.m_dwSize = sizeof(param); param.m_bMode = receiveOwn ? kUcanModeTxEcho : kUcanModeNormal; param.m_bOCR = USBCAN_OCR_DEFAULT; @@ -252,7 +220,8 @@ void SystecCanBackendPrivate::eventHandler(QEvent *event) readAllReceivedMessages(); } -bool SystecCanBackendPrivate::setConfigurationParameter(int key, const QVariant &value) +bool SystecCanBackendPrivate::setConfigurationParameter(QCanBusDevice::ConfigurationKey key, + const QVariant &value) { Q_Q(SystecCanBackend); @@ -372,19 +341,19 @@ void SystecCanBackendPrivate::startWrite() const QCanBusFrame frame = q->dequeueOutgoingFrame(); const QByteArray payload = frame.payload(); + const qsizetype payloadSize = payload.size(); - tCanMsgStruct message; - ::memset(&message, 0, sizeof(message)); + tCanMsgStruct message = {}; message.m_dwID = frame.frameId(); - message.m_bDLC = quint8(payload.size()); + message.m_bDLC = quint8(payloadSize); message.m_bFF = frame.hasExtendedFrameFormat() ? USBCAN_MSG_FF_EXT : USBCAN_MSG_FF_STD; if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) message.m_bFF |= USBCAN_MSG_FF_RTR; // remote request frame without payload else - ::memcpy(message.m_bData, payload.constData(), sizeof(message.m_bData)); + ::memcpy(message.m_bData, payload.constData(), payloadSize); const UCANRET result = ::UcanWriteCanMsgEx(handle, channel, &message, nullptr); if (Q_UNLIKELY(result != USBCAN_SUCCESSFUL)) @@ -400,11 +369,10 @@ void SystecCanBackendPrivate::readAllReceivedMessages() { Q_Q(SystecCanBackend); - QVector<QCanBusFrame> newFrames; + QList<QCanBusFrame> newFrames; for (;;) { - tCanMsgStruct message; - ::memset(&message, 0, sizeof(message)); + tCanMsgStruct message = {}; const UCANRET result = ::UcanReadCanMsgEx(handle, &channel, &message, nullptr); if (result == USBCAN_WARN_NODATA) @@ -463,8 +431,7 @@ QCanBusDevice::CanBusStatus SystecCanBackendPrivate::busStatus() { Q_Q(SystecCanBackend); - tStatusStruct status; - ::memset(&status, 0, sizeof(status)); + tStatusStruct status = {}; const UCANRET result = ::UcanGetStatus(handle, &status); if (Q_UNLIKELY(result != USBCAN_SUCCESSFUL)) { @@ -496,12 +463,6 @@ SystecCanBackend::SystecCanBackend(const QString &name, QObject *parent) : d->setupChannel(name); d->setupDefaultConfigurations(); - - std::function<void()> f = std::bind(&SystecCanBackend::resetController, this); - setResetControllerFunction(f); - - std::function<CanBusStatus()> g = std::bind(&SystecCanBackend::busStatus, this); - setCanBusStatusGetter(g); } SystecCanBackend::~SystecCanBackend() @@ -521,8 +482,8 @@ bool SystecCanBackend::open() // Apply all stored configurations except bitrate and receive own, // because these cannot be applied after opening the device - const QVector<int> keys = configurationKeys(); - for (int key : keys) { + const auto keys = configurationKeys(); + for (ConfigurationKey key : keys) { if (key == BitRateKey || key == ReceiveOwnKey) continue; const QVariant param = configurationParameter(key); @@ -546,7 +507,7 @@ void SystecCanBackend::close() setState(QCanBusDevice::UnconnectedState); } -void SystecCanBackend::setConfigurationParameter(int key, const QVariant &value) +void SystecCanBackend::setConfigurationParameter(ConfigurationKey key, const QVariant &value) { Q_D(SystecCanBackend); @@ -599,6 +560,11 @@ void SystecCanBackend::resetController() d->resetController(); } +bool SystecCanBackend::hasBusStatus() const +{ + return true; +} + QCanBusDevice::CanBusStatus SystecCanBackend::busStatus() { Q_D(SystecCanBackend); @@ -606,4 +572,14 @@ QCanBusDevice::CanBusStatus SystecCanBackend::busStatus() return d->busStatus(); } +QCanBusDeviceInfo SystecCanBackend::deviceInfo() const +{ + tUcanHardwareInfoEx hardwareInfo = {}; + UcanGetHardwareInfoEx2(d_ptr->handle, &hardwareInfo, nullptr, nullptr); + + const QString serialNumber = QString::number(hardwareInfo.m_dwSerialNr); + const QString description = descriptionString(hardwareInfo.m_dwProductCode); + return createDeviceInfo(serialNumber, description, hardwareInfo.m_bDeviceNr, d_ptr->channel); +} + QT_END_NAMESPACE diff --git a/src/plugins/canbus/systeccan/systeccanbackend.h b/src/plugins/canbus/systeccan/systeccanbackend.h index 22c1193..d222592 100644 --- a/src/plugins/canbus/systeccan/systeccanbackend.h +++ b/src/plugins/canbus/systeccan/systeccanbackend.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef SYSTECCANBACKEND_H #define SYSTECCANBACKEND_H @@ -60,7 +27,7 @@ public: bool open() override; void close() override; - void setConfigurationParameter(int key, const QVariant &value) override; + void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override; bool writeFrame(const QCanBusFrame &newData) override; @@ -75,10 +42,12 @@ public: uint deviceNumber, int channelNumber); -private: - void resetController(); - QCanBusDevice::CanBusStatus busStatus(); + void resetController() override; + bool hasBusStatus() const override; + CanBusStatus busStatus() override; + QCanBusDeviceInfo deviceInfo() const override; +private: SystecCanBackendPrivate * const d_ptr; }; diff --git a/src/plugins/canbus/systeccan/systeccanbackend_p.h b/src/plugins/canbus/systeccan/systeccanbackend_p.h index b2da322..b8acfcb 100644 --- a/src/plugins/canbus/systeccan/systeccanbackend_p.h +++ b/src/plugins/canbus/systeccan/systeccanbackend_p.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef SYSTECCANBACKEND_P_H #define SYSTECCANBACKEND_P_H @@ -58,8 +25,6 @@ QT_BEGIN_NAMESPACE class QEvent; -class QSocketNotifier; -class QWinEventNotifier; class QTimer; class IncomingEventHandler : public QObject @@ -70,7 +35,7 @@ public: QObject(parent), dptr(systecPrivate) { } - void customEvent(QEvent *event); + void customEvent(QEvent *event) override; private: SystecCanBackendPrivate * const dptr; @@ -86,7 +51,7 @@ public: bool open(); void close(); void eventHandler(QEvent *event); - bool setConfigurationParameter(int key, const QVariant &value); + bool setConfigurationParameter(QCanBusDevice::ConfigurationKey key, const QVariant &value); bool setupChannel(const QString &interfaceName); void setupDefaultConfigurations(); QString systemErrorString(int errorCode); diff --git a/src/plugins/canbus/tinycan/CMakeLists.txt b/src/plugins/canbus/tinycan/CMakeLists.txt new file mode 100644 index 0000000..b9eb5ee --- /dev/null +++ b/src/plugins/canbus/tinycan/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## TinyCanBusPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(TinyCanBusPlugin + OUTPUT_NAME qttinycanbus + PLUGIN_TYPE canbus + SOURCES + main.cpp + tinycan_symbols_p.h + tinycanbackend.cpp tinycanbackend.h tinycanbackend_p.h + LIBRARIES + Qt::Core + Qt::Network + Qt::SerialBus +) diff --git a/src/plugins/canbus/tinycan/main.cpp b/src/plugins/canbus/tinycan/main.cpp index 36fb05d..38f8140 100644 --- a/src/plugins/canbus/tinycan/main.cpp +++ b/src/plugins/canbus/tinycan/main.cpp @@ -1,39 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "tinycanbackend.h" @@ -47,11 +14,11 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_TINYCAN, "qt.canbus.plugins.tinycan") -class TinyCanBusPlugin : public QObject, public QCanBusFactoryV2 +class TinyCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") - Q_INTERFACES(QCanBusFactoryV2) + Q_INTERFACES(QCanBusFactory) public: QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override diff --git a/src/plugins/canbus/tinycan/tinycan.pro b/src/plugins/canbus/tinycan/tinycan.pro deleted file mode 100644 index c450bb9..0000000 --- a/src/plugins/canbus/tinycan/tinycan.pro +++ /dev/null @@ -1,17 +0,0 @@ -TARGET = qttinycanbus - -QT = core serialbus - -HEADERS += \ - tinycanbackend.h \ - tinycanbackend_p.h \ - tinycan_symbols_p.h - -SOURCES += main.cpp \ - tinycanbackend.cpp - -DISTFILES = plugin.json - -PLUGIN_TYPE = canbus -PLUGIN_CLASS_NAME = TinyCanBusPlugin -load(qt_plugin) diff --git a/src/plugins/canbus/tinycan/tinycan_symbols_p.h b/src/plugins/canbus/tinycan/tinycan_symbols_p.h index 625edd3..18b14a9 100644 --- a/src/plugins/canbus/tinycan/tinycan_symbols_p.h +++ b/src/plugins/canbus/tinycan/tinycan_symbols_p.h @@ -1,39 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef TINYCAN_SYMBOLS_P_H #define TINYCAN_SYMBOLS_P_H diff --git a/src/plugins/canbus/tinycan/tinycanbackend.cpp b/src/plugins/canbus/tinycan/tinycanbackend.cpp index fdd5aaa..9feb4b7 100644 --- a/src/plugins/canbus/tinycan/tinycanbackend.cpp +++ b/src/plugins/canbus/tinycan/tinycanbackend.cpp @@ -1,39 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "tinycanbackend.h" #include "tinycanbackend_p.h" @@ -74,7 +41,8 @@ bool TinyCanBackend::canCreate(QString *errorReason) QList<QCanBusDeviceInfo> TinyCanBackend::interfaces() { QList<QCanBusDeviceInfo> result; - result.append(createDeviceInfo(QStringLiteral("can0.0"))); + result.append(createDeviceInfo(QStringLiteral("tinycan"), QStringLiteral("can0.0"), + false, false)); return result; } @@ -121,7 +89,7 @@ static void DRV_CALLBACK_TYPE canRxEventCallback(quint32 index, TCanMsg *frame, Q_UNUSED(count); QMutexLocker lock(&gTinyCan->mutex); - for (TinyCanBackendPrivate *p : qAsConst(gTinyCan->channels)) { + for (TinyCanBackendPrivate *p : std::as_const(gTinyCan->channels)) { if (p->channelIndex == int(index)) { p->startRead(); return; @@ -232,7 +200,8 @@ void TinyCanBackendPrivate::close() isOpen = false; } -bool TinyCanBackendPrivate::setConfigurationParameter(int key, const QVariant &value) +bool TinyCanBackendPrivate::setConfigurationParameter(QCanBusDevice::ConfigurationKey key, + const QVariant &value) { Q_Q(TinyCanBackend); @@ -351,28 +320,23 @@ void TinyCanBackendPrivate::startWrite() const QCanBusFrame frame = q->dequeueOutgoingFrame(); const QByteArray payload = frame.payload(); - - TCanMsg message; - ::memset(&message, 0, sizeof(message)); - - if (Q_UNLIKELY(payload.size() > int(sizeof(message.Data.Bytes)))) { - qCWarning(QT_CANBUS_PLUGINS_TINYCAN, "Cannot write frame with payload size %d.", payload.size()); - } else { - message.Id = frame.frameId(); - message.Flags.Flag.Len = payload.size(); - message.Flags.Flag.Error = (frame.frameType() == QCanBusFrame::ErrorFrame); - message.Flags.Flag.RTR = (frame.frameType() == QCanBusFrame::RemoteRequestFrame); - message.Flags.Flag.TxD = 1; - message.Flags.Flag.EFF = frame.hasExtendedFrameFormat(); - - const qint32 messagesToWrite = 1; - ::memcpy(message.Data.Bytes, payload.constData(), sizeof(message.Data.Bytes)); - const int ret = ::CanTransmit(channelIndex, &message, messagesToWrite); - if (Q_UNLIKELY(ret < 0)) - q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::WriteError); - else - emit q->framesWritten(messagesToWrite); - } + const qsizetype payloadSize = payload.size(); + + TCanMsg message = {}; + message.Id = frame.frameId(); + message.Flags.Flag.Len = payloadSize; + message.Flags.Flag.Error = (frame.frameType() == QCanBusFrame::ErrorFrame); + message.Flags.Flag.RTR = (frame.frameType() == QCanBusFrame::RemoteRequestFrame); + message.Flags.Flag.TxD = 1; + message.Flags.Flag.EFF = frame.hasExtendedFrameFormat(); + + const qint32 messagesToWrite = 1; + ::memcpy(message.Data.Bytes, payload.constData(), payloadSize); + const int ret = ::CanTransmit(channelIndex, &message, messagesToWrite); + if (Q_UNLIKELY(ret < 0)) + q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::WriteError); + else + emit q->framesWritten(messagesToWrite); if (q->hasOutgoingFrames() && !writeNotifier->isActive()) writeNotifier->start(); @@ -383,22 +347,20 @@ void TinyCanBackendPrivate::startRead() { Q_Q(TinyCanBackend); - QVector<QCanBusFrame> newFrames; + QList<QCanBusFrame> newFrames; for (;;) { if (!::CanReceiveGetCount(channelIndex)) break; - TCanMsg message; - ::memset(&message, 0, sizeof(message)); + TCanMsg message = {}; const int messagesToRead = 1; const int ret = ::CanReceive(channelIndex, &message, messagesToRead); if (Q_UNLIKELY(ret < 0)) { q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ReadError); - TDeviceStatus status; - ::memset(&status, 0, sizeof(status)); + TDeviceStatus status = {}; if (::CanGetDeviceStatus(channelIndex, &status) < 0) { q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ReadError); @@ -509,9 +471,6 @@ TinyCanBackend::TinyCanBackend(const QString &name, QObject *parent) d->setupChannel(name); d->setupDefaultConfigurations(); - - std::function<void()> f = std::bind(&TinyCanBackend::resetController, this); - setResetControllerFunction(f); } TinyCanBackend::~TinyCanBackend() @@ -532,7 +491,7 @@ bool TinyCanBackend::open() // apply all stored configurations const auto keys = configurationKeys(); - for (int key : keys) { + for (ConfigurationKey key : keys) { const QVariant param = configurationParameter(key); const bool success = d->setConfigurationParameter(key, param); if (Q_UNLIKELY(!success)) { @@ -555,7 +514,7 @@ void TinyCanBackend::close() setState(QCanBusDevice::UnconnectedState); } -void TinyCanBackend::setConfigurationParameter(int key, const QVariant &value) +void TinyCanBackend::setConfigurationParameter(ConfigurationKey key, const QVariant &value) { Q_D(TinyCanBackend); @@ -611,4 +570,9 @@ void TinyCanBackend::resetController() d->resetController(); } +QCanBusDeviceInfo TinyCanBackend::deviceInfo() const +{ + return createDeviceInfo(QStringLiteral("tinycan"), QStringLiteral("can0.0"), false, false); +} + QT_END_NAMESPACE diff --git a/src/plugins/canbus/tinycan/tinycanbackend.h b/src/plugins/canbus/tinycan/tinycanbackend.h index 428e9bc..7d5b541 100644 --- a/src/plugins/canbus/tinycan/tinycanbackend.h +++ b/src/plugins/canbus/tinycan/tinycanbackend.h @@ -1,50 +1,16 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef TINYCANBACKEND_H #define TINYCANBACKEND_H -#include <QtSerialBus/qcanbusframe.h> #include <QtSerialBus/qcanbusdevice.h> #include <QtSerialBus/qcanbusdeviceinfo.h> +#include <QtSerialBus/qcanbusframe.h> -#include <QtCore/qvariant.h> -#include <QtCore/qvector.h> #include <QtCore/qlist.h> +#include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -62,7 +28,7 @@ public: bool open() override; void close() override; - void setConfigurationParameter(int key, const QVariant &value) override; + void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override; bool writeFrame(const QCanBusFrame &newData) override; @@ -71,9 +37,10 @@ public: static bool canCreate(QString *errorReason); static QList<QCanBusDeviceInfo> interfaces(); -private: - void resetController(); + void resetController() override; + QCanBusDeviceInfo deviceInfo() const override; +private: TinyCanBackendPrivate * const d_ptr; }; diff --git a/src/plugins/canbus/tinycan/tinycanbackend_p.h b/src/plugins/canbus/tinycan/tinycanbackend_p.h index 25316a2..f9f61d5 100644 --- a/src/plugins/canbus/tinycan/tinycanbackend_p.h +++ b/src/plugins/canbus/tinycan/tinycanbackend_p.h @@ -1,39 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef TINYCANBACKEND_P_H #define TINYCANBACKEND_P_H @@ -66,7 +33,7 @@ public: bool open(); void close(); - bool setConfigurationParameter(int key, const QVariant &value); + bool setConfigurationParameter(QCanBusDevice::ConfigurationKey key, const QVariant &value); QString systemErrorString(int errorCode); void setupChannel(const QString &interfaceName); diff --git a/src/plugins/canbus/vectorcan/CMakeLists.txt b/src/plugins/canbus/vectorcan/CMakeLists.txt new file mode 100644 index 0000000..e5dfbdd --- /dev/null +++ b/src/plugins/canbus/vectorcan/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## VectorCanBusPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(VectorCanBusPlugin + OUTPUT_NAME qtvectorcanbus + PLUGIN_TYPE canbus + SOURCES + main.cpp + vectorcan_symbols_p.h + vectorcanbackend.cpp vectorcanbackend.h vectorcanbackend_p.h + LIBRARIES + Qt::Core + Qt::Network + Qt::SerialBus +) diff --git a/src/plugins/canbus/vectorcan/main.cpp b/src/plugins/canbus/vectorcan/main.cpp index bbfb851..5a7ad60 100644 --- a/src/plugins/canbus/vectorcan/main.cpp +++ b/src/plugins/canbus/vectorcan/main.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "vectorcanbackend.h" @@ -46,11 +13,11 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_VECTORCAN, "qt.canbus.plugins.vectorcan") -class VectorCanBusPlugin : public QObject, public QCanBusFactoryV2 +class VectorCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") - Q_INTERFACES(QCanBusFactoryV2) + Q_INTERFACES(QCanBusFactory) public: QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override diff --git a/src/plugins/canbus/vectorcan/vectorcan.pro b/src/plugins/canbus/vectorcan/vectorcan.pro deleted file mode 100644 index 847f2aa..0000000 --- a/src/plugins/canbus/vectorcan/vectorcan.pro +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = qtvectorcanbus - -QT = core serialbus - -HEADERS += \ - vectorcanbackend.h \ - vectorcanbackend_p.h \ - vectorcan_symbols_p.h - -SOURCES += \ - main.cpp \ - vectorcanbackend.cpp - -DISTFILES = plugin.json - -PLUGIN_TYPE = canbus -PLUGIN_CLASS_NAME = VectorCanBusPlugin -load(qt_plugin) diff --git a/src/plugins/canbus/vectorcan/vectorcan_symbols_p.h b/src/plugins/canbus/vectorcan/vectorcan_symbols_p.h index 9d6e841..b8df8e4 100644 --- a/src/plugins/canbus/vectorcan/vectorcan_symbols_p.h +++ b/src/plugins/canbus/vectorcan/vectorcan_symbols_p.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef VECTORCAN_SYMBOLS_P_H #define VECTORCAN_SYMBOLS_P_H @@ -228,6 +195,8 @@ typedef HANDLE XLhandle; #define XL_EVENT_FLAG_OVERRUN 0x01 // Used in XLevent.flags +#define XL_CAN_MAX_DATA_LEN 64 + // structure for XL_RECEIVE_MSG, XL_TRANSMIT_MSG (32 bytes) struct s_xl_can_msg { unsigned long id; @@ -256,6 +225,9 @@ static_assert(sizeof(s_xl_can_msg) == 32, "Invalid size of s_xl_can_msg structur #define XL_CAN_STATE_FLAG_SJA_MODE 0x00000001 +#define XL_CANFD_RX_EVENT_HEADER_SIZE 32 +#define XL_CANFD_MAX_EVENT_SIZE 128 + // CAN Chip status struct s_xl_chip_state { unsigned char busStatus; @@ -285,6 +257,86 @@ typedef struct s_xl_event { } XLevent; static_assert(sizeof(s_xl_event) == 48, "Invalid size of s_xl_event structure"); +typedef struct { + quint32 id; + quint32 flags; + quint32 crc; + quint8 reserved1[12]; + quint16 totalBitCnt; + quint8 dlc; + quint8 reserved[5]; + quint8 data[XL_CAN_MAX_DATA_LEN]; +} XL_CAN_EV_RX_MSG; + +typedef struct { + quint32 canId; + quint32 msgFlags; + quint8 dlc; + quint8 reserved1; + quint16 reserved; + quint8 data[XL_CAN_MAX_DATA_LEN]; +} XL_CAN_EV_TX_REQUEST; + +typedef struct { + quint8 errorCode; + quint8 reserved[95]; +} XL_CAN_EV_ERROR; + +typedef struct { + quint8 busStatus; + quint8 txErrorCounter; + quint8 rxErrorCounter; + quint8 reserved; + quint32 reserved0; +} XL_CAN_EV_CHIP_STATE; + +typedef struct s_xl_sync_pulse_ev { + quint32 triggerSource; + quint32 reserved; + quint64 time; +} XL_SYNC_PULSE_EV; + +typedef XL_SYNC_PULSE_EV XL_CAN_EV_SYNC_PULSE; + +typedef struct { + quint32 size; + quint16 tag; + quint16 channelIndex; + quint32 userHandle; + quint16 flagsChip; + quint16 reserved0; + quint64 reserved1; + quint64 timeStamp; + union { + quint8 raw[XL_CANFD_MAX_EVENT_SIZE - XL_CANFD_RX_EVENT_HEADER_SIZE]; + XL_CAN_EV_RX_MSG canRxOkMsg; + XL_CAN_EV_RX_MSG canTxOkMsg; + XL_CAN_EV_TX_REQUEST canTxRequest; + XL_CAN_EV_ERROR canError; + XL_CAN_EV_CHIP_STATE canChipState; + XL_CAN_EV_SYNC_PULSE canSyncPulse; + } tagData; +} XLcanRxEvent; + +typedef struct { + quint32 id; + quint32 flags; + quint8 dlc; + quint8 reserved[7]; + quint8 data[XL_CAN_MAX_DATA_LEN]; +} XL_CAN_TX_MSG; + +typedef struct { + quint16 tag; + quint16 transId; + quint8 channelIndex; + quint8 reserved[3]; + union { + XL_CAN_TX_MSG canMsg; + } tagData; +} XLcanTxEvent; + + // build a channels mask from the channels index #define XL_CHANNEL_MASK(x) (quint64(1) << (x)) @@ -354,6 +406,22 @@ typedef qint16 XLstatus; #define XL_CAN_STD 01 // flag for standard ID's #define XL_CAN_EXT 02 // flag for extended ID's +#define XL_CAN_TXMSG_FLAG_EDL 0x0001 // extended data length +#define XL_CAN_TXMSG_FLAG_BRS 0x0002 // baud rate switch +#define XL_CAN_TXMSG_FLAG_RTR 0x0010 // remote transmission request +#define XL_CAN_TXMSG_FLAG_HIGHPRIO 0x0080 // high priority message - clears all send buffers - then transmits +#define XL_CAN_TXMSG_FLAG_WAKEUP 0x0200 // generate a wakeup message + +#define XL_CAN_RXMSG_FLAG_EDL 0x0001 // extended data length +#define XL_CAN_RXMSG_FLAG_BRS 0x0002 // baud rate switch +#define XL_CAN_RXMSG_FLAG_ESI 0x0004 // error state indicator +#define XL_CAN_RXMSG_FLAG_RTR 0x0010 // remote transmission request +#define XL_CAN_RXMSG_FLAG_EF 0x0200 // error frame (only posssible in XL_CAN_EV_TX_REQUEST/XL_CAN_EV_TX_REMOVED) +#define XL_CAN_RXMSG_FLAG_ARB_LOST 0x0400 // Arbitration Lost + // set if the receiving node tried to transmit a message but lost arbitration process +#define XL_CAN_RXMSG_FLAG_WAKEUP 0x2000 // high voltage message on single wire CAN +#define XL_CAN_RXMSG_FLAG_TE 0x4000 // 1: transceiver error detected + typedef struct { quint32 busType; union { @@ -447,6 +515,21 @@ typedef struct _XLacceptance { XLaccFilt xtd; } XLacceptance; +typedef struct s_XLcanFdConf { + unsigned int arbitrationBitRate; + unsigned int sjwAbr; + unsigned int tseg1Abr; + unsigned int tseg2Abr; + unsigned int dataBitRate; + unsigned int sjwDbr; + unsigned int tseg1Dbr; + unsigned int tseg2Dbr; + unsigned char reserved; + unsigned char options; + unsigned char reserved1[2]; + unsigned int reserved2; +} XLcanFdConf; + // defines for xlSetGlobalTimeSync #define XL_SET_TIMESYNC_NO_CHANGE ((unsigned long)0) #define XL_SET_TIMESYNC_ON ((unsigned long)1) @@ -476,6 +559,10 @@ GENERATE_SYMBOL_VARIABLE(XLstatus, xlReceive, XLportHandle, quint32 *, XLevent * GENERATE_SYMBOL_VARIABLE(XLstatus, xlSetNotification, XLportHandle, XLhandle *, int) GENERATE_SYMBOL_VARIABLE(XLstatus, xlCanRequestChipState, XLportHandle, XLaccess) GENERATE_SYMBOL_VARIABLE(char *, xlGetErrorString, XLstatus) +GENERATE_SYMBOL_VARIABLE(XLstatus, xlCanFdSetConfiguration, XLportHandle, XLaccess, XLcanFdConf *) +GENERATE_SYMBOL_VARIABLE(XLstatus, xlCanReceive, XLportHandle, XLcanRxEvent *) +GENERATE_SYMBOL_VARIABLE(XLstatus, xlCanTransmitEx, XLportHandle, XLaccess, quint32, quint32 *, XLcanTxEvent *) +GENERATE_SYMBOL_VARIABLE(XLaccess, xlGetChannelMask, int, int, int) inline bool resolveVectorCanSymbols(QLibrary *vectorcanLibrary) { @@ -502,7 +589,10 @@ inline bool resolveVectorCanSymbols(QLibrary *vectorcanLibrary) RESOLVE_SYMBOL(xlSetNotification) RESOLVE_SYMBOL(xlCanRequestChipState) RESOLVE_SYMBOL(xlGetErrorString) - + RESOLVE_SYMBOL(xlCanFdSetConfiguration) + RESOLVE_SYMBOL(xlCanTransmitEx) + RESOLVE_SYMBOL(xlCanReceive) + RESOLVE_SYMBOL(xlGetChannelMask) return true; } diff --git a/src/plugins/canbus/vectorcan/vectorcanbackend.cpp b/src/plugins/canbus/vectorcan/vectorcanbackend.cpp index 0382d66..c7ec84c 100644 --- a/src/plugins/canbus/vectorcan/vectorcanbackend.cpp +++ b/src/plugins/canbus/vectorcan/vectorcanbackend.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "vectorcanbackend.h" #include "vectorcanbackend_p.h" @@ -86,6 +53,8 @@ QList<QCanBusDeviceInfo> VectorCanBackend::interfaces() for (uint i = 0; i < config.channelCount; ++i) { if (config.channel[i].hwType == XL_HWTYPE_NONE) continue; + if (!(config.channel[i].channelBusCapabilities & XL_BUS_ACTIVE_CAP_CAN)) + continue; const bool isVirtual = config.channel[i].hwType == XL_HWTYPE_VIRTUAL; const bool isFd = config.channel[i].channelCapabilities & XL_CHANNEL_FLAG_CANFD_SUPPORT; @@ -93,8 +62,9 @@ QList<QCanBusDeviceInfo> VectorCanBackend::interfaces() const QString name = QStringLiteral("can") + QString::number(i); const QString serial = QString::number(config.channel[i].serialNumber); const QString description = QLatin1String(config.channel[i].name); - result.append(std::move(createDeviceInfo(name, serial, description, channel, - isVirtual, isFd))); + result.append(createDeviceInfo(QStringLiteral("vectorcan"), name, + serial, description, QString(), + channel, isVirtual, isFd)); } VectorCanBackendPrivate::cleanupDriver(); @@ -112,16 +82,10 @@ public: , dptr(d) { setHandle(dptr->readHandle); - } -protected: - bool event(QEvent *e) override - { - if (e->type() == QEvent::WinEventAct) { + connect(this, &QWinEventNotifier::activated, this, [this]() { dptr->startRead(); - return true; - } - return QWinEventNotifier::event(e); + }); } private: @@ -153,6 +117,79 @@ private: VectorCanBackendPrivate * const dptr; }; +XLcanFdConf xlCanFdConfInit(int arbitrationBitRate, int dataBitRate) +{ + XLcanFdConf conf = {}; + const int minArbitrationBitRate = 5000; + if (arbitrationBitRate < minArbitrationBitRate) { + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, + "Arbitration bit rate %d is to low (Minimum: %d)", + arbitrationBitRate, minArbitrationBitRate); + return conf; + } + if (dataBitRate < arbitrationBitRate) { + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, + "Data bit rate %d must not be lower than arbitration bit rate %d", + dataBitRate, arbitrationBitRate); + return conf; + } + + int prescalerArbitration = 1; + switch (arbitrationBitRate) { + case 5000: prescalerArbitration = 50; break; + case 10000: prescalerArbitration = 25; break; + case 20000: prescalerArbitration = 20; break; + case 33333: prescalerArbitration = 8; break; + case 50000: prescalerArbitration = 5; break; + case 83333: prescalerArbitration = 3; break; + case 100000: prescalerArbitration = 4; break; + case 125000: prescalerArbitration = 2; break; + } + conf.arbitrationBitRate = arbitrationBitRate; + const int clock = 80000000; + double samplePoint = 0.75; + const int btlCyclesAbr = clock / conf.arbitrationBitRate / prescalerArbitration; + conf.tseg1Abr = (btlCyclesAbr * samplePoint) - 1; + conf.tseg2Abr = btlCyclesAbr * (1 - samplePoint); + conf.sjwAbr = conf.tseg2Abr; + + int prescalerData = 1; + switch (dataBitRate) { + case 25000: prescalerData = 20; break; + case 50000: prescalerData = 10; break; + case 83333: prescalerData = 6; break; + case 100000: prescalerData = 5; break; + case 125000: prescalerData = 4; break; + case 250000: prescalerData = 2; break; + case 8000000: samplePoint = 0.70; break; + } + conf.dataBitRate = dataBitRate; + const int btlCyclesDbr = clock / conf.dataBitRate / prescalerData; + conf.tseg1Dbr = (btlCyclesDbr * samplePoint) - 1; + conf.tseg2Dbr = btlCyclesDbr * (1 - samplePoint); + conf.sjwDbr = conf.tseg2Dbr; + + return conf; +} + +static qsizetype getDlcFromPayloadSize(const qsizetype size) +{ + if (size <= 8) + return size; + if (size <= 12) + return 9; + if (size <= 16) + return 10; + if (size <= 20) + return 11; + if (size <= 24) + return 12; + if (size <= 32) + return 13; + if (size <= 48) + return 14; + return 15; +} VectorCanBackendPrivate::VectorCanBackendPrivate(VectorCanBackend *q) : q_ptr(q) @@ -170,18 +207,48 @@ bool VectorCanBackendPrivate::open() Q_Q(VectorCanBackend); { + XLdriverConfig config; + if (Q_UNLIKELY(::xlGetDriverConfig(&config) != XL_SUCCESS)) { + q->setError(VectorCanBackend::tr("Unable to get driver configuration"), + QCanBusDevice::CanBusError::ConnectionError); + return false; + } + channelMask = config.channel[channelIndex].channelMask; XLaccess permissionMask = channelMask; - const quint32 queueSize = 256; + const quint32 queueSize = usesCanFd ? 8192 : 256; const XLstatus status = ::xlOpenPort(&portHandle, const_cast<char *>(qPrintable(qApp->applicationName())), channelMask, &permissionMask, queueSize, - XL_INTERFACE_VERSION, XL_BUS_TYPE_CAN); + usesCanFd ? XL_INTERFACE_VERSION_V4 : XL_INTERFACE_VERSION, XL_BUS_TYPE_CAN); if (Q_UNLIKELY(status != XL_SUCCESS || portHandle == XL_INVALID_PORTHANDLE)) { q->setError(systemErrorString(status), QCanBusDevice::ConnectionError); portHandle = XL_INVALID_PORTHANDLE; return false; } + if (usesCanFd && arbBitRate != 0) { + if (permissionMask != 0) { + XLcanFdConf xlfdconf = xlCanFdConfInit(arbBitRate, dataBitRate); + + const XLstatus statusFd = ::xlCanFdSetConfiguration(portHandle, channelMask, &xlfdconf); + if (Q_UNLIKELY(statusFd != XL_SUCCESS)) { + const QString errorString = systemErrorString(statusFd); + if (statusFd == XL_ERR_INVALID_ACCESS) { + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "Unable to change the configuration: %ls.", + qUtf16Printable(errorString)); + q->setError(errorString, QCanBusDevice::CanBusError::ConfigurationError); + } else { + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "Connection error: %ls.", + qUtf16Printable(errorString)); + q->setError(errorString, QCanBusDevice::CanBusError::ConnectionError); + return false; + } + } + } else { + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "No init access for channel %d! " + "Using existing configuration!", channelIndex); + } + } } { @@ -242,7 +309,8 @@ void VectorCanBackendPrivate::close() portHandle = XL_INVALID_PORTHANDLE; } -bool VectorCanBackendPrivate::setConfigurationParameter(int key, const QVariant &value) +bool VectorCanBackendPrivate::setConfigurationParameter(QCanBusDevice::ConfigurationKey key, + const QVariant &value) { Q_Q(VectorCanBackend); @@ -252,8 +320,27 @@ bool VectorCanBackendPrivate::setConfigurationParameter(int key, const QVariant case QCanBusDevice::ReceiveOwnKey: transmitEcho = value.toBool(); return true; + case QCanBusDevice::DataBitRateKey: + return setDataBitRate(value.toUInt()); + case QCanBusDevice::CanFdKey: + { + if (value.toBool()) { + XLdriverConfig config; + if (Q_UNLIKELY(::xlGetDriverConfig(&config) == XL_SUCCESS)) { + if (config.channel[channelIndex].channelCapabilities & XL_CHANNEL_FLAG_CANFD_SUPPORT) { + usesCanFd = true; + return true; + } + } + q->setError(VectorCanBackend::tr("Unable to set CAN FD"), + QCanBusDevice::CanBusError::ConfigurationError); + return false; + } + usesCanFd = false; + return true; + } default: - q->setError(VectorCanBackend::tr("Unsupported configuration key"), + q->setError(VectorCanBackend::tr("Unsupported configuration key: %1").arg(key), QCanBusDevice::ConfigurationError); return false; } @@ -261,13 +348,18 @@ bool VectorCanBackendPrivate::setConfigurationParameter(int key, const QVariant 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; - const int channelIndex = ref.toInt(&ok); + channelIndex = ref.toInt(&ok); if (ok && (channelIndex >= 0 && channelIndex < XL_CONFIG_MAX_CHANNELS)) { - channelMask = XL_CHANNEL_MASK((channelIndex)); + channelMask = xlGetChannelMask(-1, channelIndex, 0); return; + } else { + channelIndex = -1; + q->setError(VectorCanBackend::tr("Unable to setup channel with interface name %1") + .arg(interfaceName), QCanBusDevice::CanBusError::ConfigurationError); } } @@ -301,30 +393,51 @@ void VectorCanBackendPrivate::startWrite() const QCanBusFrame frame = q->dequeueOutgoingFrame(); const QByteArray payload = frame.payload(); + const qsizetype payloadSize = payload.size(); - XLevent event; - ::memset(&event, 0, sizeof(event)); - - event.tag = XL_TRANSMIT_MSG; - - s_xl_can_msg &msg = event.tagData.msg; + quint32 eventCount = 1; + XLstatus status = XL_ERROR; + if (usesCanFd) { + XLcanTxEvent event = {}; + + event.tag = XL_CAN_EV_TAG_TX_MSG; + XL_CAN_TX_MSG &msg = event.tagData.canMsg; + + msg.id = frame.frameId(); + if (frame.hasExtendedFrameFormat()) + msg.id |= XL_CAN_EXT_MSG_ID; + + msg.dlc = static_cast<quint8>(getDlcFromPayloadSize(payloadSize)); + if (frame.hasFlexibleDataRateFormat()) + msg.flags = XL_CAN_TXMSG_FLAG_EDL; + if (frame.hasBitrateSwitch()) + msg.flags |= XL_CAN_TXMSG_FLAG_BRS; + if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) + msg.flags |= XL_CAN_TXMSG_FLAG_RTR; // we do not care about the payload + else + ::memcpy(msg.data, payload.constData(), payloadSize); + + status = ::xlCanTransmitEx(portHandle, channelMask, eventCount, &eventCount, &event); + } else { + XLevent event = {}; + event.tag = XL_TRANSMIT_MSG; + s_xl_can_msg &msg = event.tagData.msg; - msg.id = frame.frameId(); - if (frame.hasExtendedFrameFormat()) - msg.id |= XL_CAN_EXT_MSG_ID; + msg.id = frame.frameId(); + if (frame.hasExtendedFrameFormat()) + msg.id |= XL_CAN_EXT_MSG_ID; - msg.dlc = payload.size(); + msg.dlc = payloadSize; - if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) - msg.flags |= XL_CAN_MSG_FLAG_REMOTE_FRAME; // we do not care about the payload - else if (frame.frameType() == QCanBusFrame::ErrorFrame) - msg.flags |= XL_CAN_MSG_FLAG_ERROR_FRAME; // we do not care about the payload - else - ::memcpy(msg.data, payload.constData(), sizeof(msg.data)); + if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) + msg.flags |= XL_CAN_MSG_FLAG_REMOTE_FRAME; // we do not care about the payload + else if (frame.frameType() == QCanBusFrame::ErrorFrame) + msg.flags |= XL_CAN_MSG_FLAG_ERROR_FRAME; // we do not care about the payload + else + ::memcpy(msg.data, payload.constData(), payloadSize); - quint32 eventCount = 1; - const XLstatus status = ::xlCanTransmit(portHandle, channelMask, - &eventCount, &event); + status = ::xlCanTransmit(portHandle, channelMask, &eventCount, &event); + } if (Q_UNLIKELY(status != XL_SUCCESS)) { q->setError(systemErrorString(status), QCanBusDevice::WriteError); @@ -340,42 +453,80 @@ void VectorCanBackendPrivate::startRead() { Q_Q(VectorCanBackend); - QVector<QCanBusFrame> newFrames; + QList<QCanBusFrame> newFrames; for (;;) { quint32 eventCount = 1; - XLevent event; - ::memset(&event, 0, sizeof(event)); + if (usesCanFd) { + XLcanRxEvent event = {}; + + const XLstatus status = ::xlCanReceive(portHandle, &event); + if (Q_UNLIKELY(status != XL_SUCCESS)) { + if (status != XL_ERR_QUEUE_IS_EMPTY) { + q->setError(systemErrorString(status), QCanBusDevice::ReadError); + } + break; + } + if (event.tag != XL_CAN_EV_TAG_RX_OK) + continue; + + const XL_CAN_EV_RX_MSG &msg = event.tagData.canRxOkMsg; + + int dataLength = msg.dlc; + switch (msg.dlc) { + case 9: dataLength = 12; break; + case 10: dataLength = 16; break; + case 11: dataLength = 20; break; + case 12: dataLength = 24; break; + case 13: dataLength = 32; break; + case 14: dataLength = 48; break; + case 15: dataLength = 64; break; + } - const XLstatus status = ::xlReceive(portHandle, &eventCount, &event); - if (Q_UNLIKELY(status != XL_SUCCESS)) { - if (status != XL_ERR_QUEUE_IS_EMPTY) { - q->setError(systemErrorString(status), - QCanBusDevice::ReadError); + QCanBusFrame frame(msg.id & ~XL_CAN_EXT_MSG_ID, + QByteArray(reinterpret_cast<const char *>(msg.data), dataLength)); + frame.setTimeStamp(QCanBusFrame::TimeStamp::fromMicroSeconds(event.timeStamp / 1000)); + frame.setExtendedFrameFormat(msg.id & XL_CAN_EXT_MSG_ID); + frame.setBitrateSwitch(msg.flags & XL_CAN_RXMSG_FLAG_BRS); + frame.setFrameType((msg.flags & XL_CAN_RXMSG_FLAG_RTR) + ? QCanBusFrame::RemoteRequestFrame + : (msg.flags & XL_CAN_RXMSG_FLAG_EF) + ? QCanBusFrame::ErrorFrame + : QCanBusFrame::DataFrame); + + newFrames.append(std::move(frame)); + } else { + XLevent event = {}; + + const XLstatus status = ::xlReceive(portHandle, &eventCount, &event); + if (Q_UNLIKELY(status != XL_SUCCESS)) { + if (status != XL_ERR_QUEUE_IS_EMPTY) { + q->setError(systemErrorString(status), + QCanBusDevice::ReadError); + } + break; } - break; + if (event.tag != XL_RECEIVE_MSG) + continue; + + const s_xl_can_msg &msg = event.tagData.msg; + + if ((msg.flags & XL_CAN_MSG_FLAG_TX_COMPLETED) && !transmitEcho) + continue; + + QCanBusFrame frame(msg.id & ~XL_CAN_EXT_MSG_ID, + QByteArray(reinterpret_cast<const char *>(msg.data), int(msg.dlc))); + frame.setTimeStamp(QCanBusFrame::TimeStamp::fromMicroSeconds(event.timeStamp / 1000)); + frame.setExtendedFrameFormat(msg.id & XL_CAN_EXT_MSG_ID); + frame.setLocalEcho(msg.flags & XL_CAN_MSG_FLAG_TX_COMPLETED); + frame.setFrameType((msg.flags & XL_CAN_MSG_FLAG_REMOTE_FRAME) + ? QCanBusFrame::RemoteRequestFrame + : (msg.flags & XL_CAN_MSG_FLAG_ERROR_FRAME) + ? QCanBusFrame::ErrorFrame + : QCanBusFrame::DataFrame); + + newFrames.append(std::move(frame)); } - - if (event.tag != XL_RECEIVE_MSG) - continue; - - const s_xl_can_msg &msg = event.tagData.msg; - - if ((msg.flags & XL_CAN_MSG_FLAG_TX_COMPLETED) && !transmitEcho) - continue; - - QCanBusFrame frame(msg.id & ~XL_CAN_EXT_MSG_ID, - QByteArray(reinterpret_cast<const char *>(msg.data), int(msg.dlc))); - frame.setTimeStamp(QCanBusFrame::TimeStamp::fromMicroSeconds(event.timeStamp / 1000)); - frame.setExtendedFrameFormat(msg.id & XL_CAN_EXT_MSG_ID); - frame.setLocalEcho(msg.flags & XL_CAN_MSG_FLAG_TX_COMPLETED); - frame.setFrameType((msg.flags & XL_CAN_MSG_FLAG_REMOTE_FRAME) - ? QCanBusFrame::RemoteRequestFrame - : (msg.flags & XL_CAN_MSG_FLAG_ERROR_FRAME) - ? QCanBusFrame::ErrorFrame - : QCanBusFrame::DataFrame); - - newFrames.append(std::move(frame)); } q->enqueueReceivedFrames(newFrames); @@ -425,19 +576,40 @@ void VectorCanBackendPrivate::cleanupDriver() bool VectorCanBackendPrivate::setBitRate(quint32 bitrate) { Q_Q(VectorCanBackend); - - if (q->state() != QCanBusDevice::UnconnectedState) { + if (!usesCanFd && q->state() != QCanBusDevice::UnconnectedState) { const XLstatus status = ::xlCanSetChannelBitrate(portHandle, channelMask, bitrate); + arbBitRate = bitrate; if (Q_UNLIKELY(status != XL_SUCCESS)) { q->setError(systemErrorString(status), QCanBusDevice::CanBusError::ConfigurationError); return false; } + } else if (arbBitRate != bitrate) { + arbBitRate = bitrate; } return true; } +bool VectorCanBackendPrivate::setDataBitRate(quint32 bitrate) +{ + if (!usesCanFd) { + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, + "Cannot set data bit rate in CAN 2.0 mode, this is only available with CAN FD"); + return false; + } + if (dataBitRate != bitrate) { + if (bitrate >= 25000) { // Minimum + dataBitRate = bitrate; + } else { + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, + "Cannot set data bit rate to less than 25000 which is the minimum"); + return false; + } + } + return true; +} + VectorCanBackend::VectorCanBackend(const QString &name, QObject *parent) : QCanBusDevice(parent) , d_ptr(new VectorCanBackendPrivate(this)) @@ -446,9 +618,6 @@ VectorCanBackend::VectorCanBackend(const QString &name, QObject *parent) d->setupChannel(name); d->setupDefaultConfigurations(); - - std::function<CanBusStatus()> g = std::bind(&VectorCanBackend::busStatus, this); - setCanBusStatusGetter(g); } VectorCanBackend::~VectorCanBackend() @@ -469,7 +638,7 @@ bool VectorCanBackend::open() } const auto keys = configurationKeys(); - for (int key : keys) { + for (ConfigurationKey key : keys) { const QVariant param = configurationParameter(key); const bool success = d->setConfigurationParameter(key, param); if (!success) { @@ -491,7 +660,7 @@ void VectorCanBackend::close() setState(QCanBusDevice::UnconnectedState); } -void VectorCanBackend::setConfigurationParameter(int key, const QVariant &value) +void VectorCanBackend::setConfigurationParameter(ConfigurationKey key, const QVariant &value) { Q_D(VectorCanBackend); @@ -520,9 +689,8 @@ bool VectorCanBackend::writeFrame(const QCanBusFrame &newData) return false; } - // CAN FD frame format not implemented at this stage - if (Q_UNLIKELY(newData.hasFlexibleDataRateFormat())) { - setError(tr("CAN FD frame format not supported."), + if (!d->usesCanFd && newData.hasFlexibleDataRateFormat()) { + setError(tr("Unable to write a flexible data rate format frame without CAN FD enabled."), QCanBusDevice::WriteError); return false; } @@ -543,6 +711,11 @@ QString VectorCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame) return QString(); } +bool VectorCanBackend::hasBusStatus() const +{ + return true; +} + QCanBusDevice::CanBusStatus VectorCanBackend::busStatus() { Q_D(VectorCanBackend); @@ -556,35 +729,71 @@ QCanBusDevice::CanBusStatus VectorCanBackend::busStatus() return QCanBusDevice::CanBusStatus::Unknown; } - quint32 eventCount = 1; - XLevent event; - ::memset(&event, 0, sizeof(event)); + quint8 busStatus = 0; + if (d->usesCanFd) { + XLcanRxEvent event = {}; + + const XLstatus receiveStatus = ::xlCanReceive(d->portHandle, &event); + if (Q_UNLIKELY(receiveStatus != XL_SUCCESS)) { + const QString errorString = d->systemErrorString(receiveStatus); + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "Can not query CAN bus status: %ls.", + qUtf16Printable(errorString)); + setError(errorString, QCanBusDevice::CanBusError::ReadError); + return QCanBusDevice::CanBusStatus::Unknown; + } - const XLstatus receiveStatus = ::xlReceive(d->portHandle, &eventCount, &event); - if (Q_UNLIKELY(receiveStatus != XL_SUCCESS)) { - const QString errorString = d->systemErrorString(receiveStatus); - qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "Can not query CAN bus status: %ls.", - qUtf16Printable(errorString)); - setError(errorString, QCanBusDevice::CanBusError::ReadError); - return QCanBusDevice::CanBusStatus::Unknown; - } + if (Q_LIKELY(event.tag == XL_CAN_EV_TAG_CHIP_STATE)) + busStatus = event.tagData.canChipState.busStatus; - if (Q_LIKELY(event.tag == XL_CHIP_STATE)) { - switch (event.tagData.chipState.busStatus) { - case XL_CHIPSTAT_BUSOFF: - return QCanBusDevice::CanBusStatus::BusOff; - case XL_CHIPSTAT_ERROR_PASSIVE: - return QCanBusDevice::CanBusStatus::Error; - case XL_CHIPSTAT_ERROR_WARNING: - return QCanBusDevice::CanBusStatus::Warning; - case XL_CHIPSTAT_ERROR_ACTIVE: - return QCanBusDevice::CanBusStatus::Good; + } else { + quint32 eventCount = 1; + XLevent event = {}; + + const XLstatus receiveStatus = ::xlReceive(d->portHandle, &eventCount, &event); + if (Q_UNLIKELY(receiveStatus != XL_SUCCESS)) { + const QString errorString = d->systemErrorString(receiveStatus); + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "Can not query CAN bus status: %ls.", + qUtf16Printable(errorString)); + setError(errorString, QCanBusDevice::CanBusError::ReadError); + return QCanBusDevice::CanBusStatus::Unknown; } + + if (Q_LIKELY(event.tag == XL_CHIP_STATE)) + busStatus = event.tagData.chipState.busStatus; + } + + switch (busStatus) { + case XL_CHIPSTAT_BUSOFF: + return QCanBusDevice::CanBusStatus::BusOff; + case XL_CHIPSTAT_ERROR_PASSIVE: + return QCanBusDevice::CanBusStatus::Error; + case XL_CHIPSTAT_ERROR_WARNING: + return QCanBusDevice::CanBusStatus::Warning; + case XL_CHIPSTAT_ERROR_ACTIVE: + return QCanBusDevice::CanBusStatus::Good; } - qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "Unknown CAN bus status: %u", - uint(event.tagData.chipState.busStatus)); + qCWarning(QT_CANBUS_PLUGINS_VECTORCAN, "Unknown CAN bus status: %u", busStatus); return QCanBusDevice::CanBusStatus::Unknown; } +QCanBusDeviceInfo VectorCanBackend::deviceInfo() const +{ + const QList<QCanBusDeviceInfo> availableDevices = interfaces(); + const int index = d_ptr->channelIndex; + const QString name = QStringLiteral("can%1").arg(index); + + const auto deviceInfo = std::find_if(availableDevices.constBegin(), + availableDevices.constEnd(), + [name](const QCanBusDeviceInfo &info) { + return name == info.name(); + }); + + if (Q_LIKELY(deviceInfo != availableDevices.constEnd())) + return *deviceInfo; + + qWarning("%s: Cannot get device info for index %d.", Q_FUNC_INFO, index); + return QCanBusDevice::deviceInfo(); +} + QT_END_NAMESPACE diff --git a/src/plugins/canbus/vectorcan/vectorcanbackend.h b/src/plugins/canbus/vectorcan/vectorcanbackend.h index 89b9da6..1b08dbc 100644 --- a/src/plugins/canbus/vectorcan/vectorcanbackend.h +++ b/src/plugins/canbus/vectorcan/vectorcanbackend.h @@ -1,49 +1,15 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef VECTORCANBACKEND_H #define VECTORCANBACKEND_H -#include <QtSerialBus/qcanbusframe.h> #include <QtSerialBus/qcanbusdevice.h> #include <QtSerialBus/qcanbusdeviceinfo.h> +#include <QtSerialBus/qcanbusframe.h> -#include <QtCore/qvariant.h> -#include <QtCore/qvector.h> #include <QtCore/qlist.h> +#include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -61,7 +27,7 @@ public: bool open() override; void close() override; - void setConfigurationParameter(int key, const QVariant &value) override; + void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override; bool writeFrame(const QCanBusFrame &newData) override; @@ -70,9 +36,11 @@ public: static bool canCreate(QString *errorReason); static QList<QCanBusDeviceInfo> interfaces(); -private: - QCanBusDevice::CanBusStatus busStatus(); + bool hasBusStatus() const override; + CanBusStatus busStatus() override; + QCanBusDeviceInfo deviceInfo() const override; +private: VectorCanBackendPrivate * const d_ptr; }; diff --git a/src/plugins/canbus/vectorcan/vectorcanbackend_p.h b/src/plugins/canbus/vectorcan/vectorcanbackend_p.h index 3eafb0c..fefd8f7 100644 --- a/src/plugins/canbus/vectorcan/vectorcanbackend_p.h +++ b/src/plugins/canbus/vectorcan/vectorcanbackend_p.h @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef VECTORCANBACKEND_P_H #define VECTORCANBACKEND_P_H @@ -71,7 +38,7 @@ public: bool open(); void close(); - bool setConfigurationParameter(int key, const QVariant &value); + bool setConfigurationParameter(QCanBusDevice::ConfigurationKey key, const QVariant &value); void setupChannel(const QString &interfaceName); void setupDefaultConfigurations(); QString systemErrorString(int errorCode) const; @@ -81,6 +48,7 @@ public: void startupDriver(); static void cleanupDriver(); bool setBitRate(quint32 bitrate); + bool setDataBitRate(quint32 bitrate); VectorCanBackend * const q_ptr; @@ -90,6 +58,10 @@ public: HANDLE readHandle = INVALID_HANDLE_VALUE; QTimer *writeNotifier = nullptr; QWinEventNotifier *readNotifier = nullptr; + quint32 dataBitRate = 0; + quint32 arbBitRate = 0; + int channelIndex = -1; + bool usesCanFd = false; }; QT_END_NAMESPACE diff --git a/src/plugins/canbus/virtualcan/CMakeLists.txt b/src/plugins/canbus/virtualcan/CMakeLists.txt new file mode 100644 index 0000000..1b7b4ba --- /dev/null +++ b/src/plugins/canbus/virtualcan/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## VirtualCanBusPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(VirtualCanBusPlugin + OUTPUT_NAME qtvirtualcanbus + PLUGIN_TYPE canbus + SOURCES + main.cpp + virtualcanbackend.cpp virtualcanbackend.h + LIBRARIES + Qt::Core + Qt::Network + Qt::SerialBus +) diff --git a/src/plugins/canbus/virtualcan/main.cpp b/src/plugins/canbus/virtualcan/main.cpp index 287b95a..8bf8121 100644 --- a/src/plugins/canbus/virtualcan/main.cpp +++ b/src/plugins/canbus/virtualcan/main.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "virtualcanbackend.h" @@ -46,11 +13,11 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_VIRTUALCAN, "qt.canbus.plugins.virtualcan") -class VirtualCanBusPlugin : public QObject, public QCanBusFactoryV2 +class VirtualCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") - Q_INTERFACES(QCanBusFactoryV2) + Q_INTERFACES(QCanBusFactory) public: QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override diff --git a/src/plugins/canbus/virtualcan/virtualcan.pro b/src/plugins/canbus/virtualcan/virtualcan.pro deleted file mode 100644 index d719f70..0000000 --- a/src/plugins/canbus/virtualcan/virtualcan.pro +++ /dev/null @@ -1,16 +0,0 @@ -TARGET = qtvirtualcanbus - -QT = core network serialbus - -HEADERS += \ - virtualcanbackend.h - -SOURCES += \ - main.cpp \ - virtualcanbackend.cpp - -DISTFILES = plugin.json - -PLUGIN_TYPE = canbus -PLUGIN_CLASS_NAME = VirtualCanBusPlugin -load(qt_plugin) diff --git a/src/plugins/canbus/virtualcan/virtualcanbackend.cpp b/src/plugins/canbus/virtualcan/virtualcanbackend.cpp index 0057d9f..c901669 100644 --- a/src/plugins/canbus/virtualcan/virtualcanbackend.cpp +++ b/src/plugins/canbus/virtualcan/virtualcanbackend.cpp @@ -1,38 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "virtualcanbackend.h" @@ -45,6 +12,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::Literals::StringLiterals; + Q_DECLARE_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_VIRTUALCAN) enum { @@ -139,12 +108,13 @@ void VirtualCanServer::readyRead() QStringList list = interfaces.toStringList(); list.removeAll(command.mid(int(strlen("disconnect:")))); readSocket->setProperty("interfaces", list); + readSocket->disconnectFromHost(); } else { const QByteArrayList commandList = command.split(':'); Q_ASSERT(commandList.size() == 2); - for (QTcpSocket *writeSocket : qAsConst(m_serverSockets)) { + for (QTcpSocket *writeSocket : std::as_const(m_serverSockets)) { // Don't send the frame back to its origin if (writeSocket == readSocket) continue; @@ -218,12 +188,12 @@ bool VirtualCanBackend::open() void VirtualCanBackend::close() { - setState(ClosingState); + qCDebug(QT_CANBUS_PLUGINS_VIRTUALCAN, "Client [%p] sends disconnect to server.", this); - m_clientSocket->write("disconnect:can" + QByteArray::number(m_channel) + '\n'); + m_clientSocket->write(QByteArray("disconnect:can"_ba + QByteArray::number(m_channel) + '\n')); } -void VirtualCanBackend::setConfigurationParameter(int key, const QVariant &value) +void VirtualCanBackend::setConfigurationParameter(ConfigurationKey key, const QVariant &value) { if (key == QCanBusDevice::ReceiveOwnKey || key == QCanBusDevice::CanFdKey) QCanBusDevice::setConfigurationParameter(key, value); @@ -289,6 +259,7 @@ bool VirtualCanBackend::writeFrame(const QCanBusFrame &frame) enqueueReceivedFrames({echoFrame}); } + emit framesWritten(qint64(1)); return true; } @@ -298,24 +269,34 @@ QString VirtualCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame) return QString(); } +QCanBusDeviceInfo VirtualCanBackend::virtualCanDeviceInfo(uint channel) +{ + return createDeviceInfo( + QStringLiteral("virtualcan"), + QStringLiteral("can%1").arg(channel), QString(), + QStringLiteral("Qt Virtual CAN bus"), QString(), + channel, true, true); +} + QList<QCanBusDeviceInfo> VirtualCanBackend::interfaces() { QList<QCanBusDeviceInfo> result; - for (int channel = 0; channel < VirtualChannels; ++channel) { - result.append(std::move(createDeviceInfo( - QStringLiteral("can%1").arg(channel), QString(), - QStringLiteral("Qt Virtual CAN bus"), channel, - true, true))); - } + for (uint channel = 0; channel < VirtualChannels; ++channel) + result.append(virtualCanDeviceInfo(channel)); return result; } +QCanBusDeviceInfo VirtualCanBackend::deviceInfo() const +{ + return virtualCanDeviceInfo(m_channel); +} + void VirtualCanBackend::clientConnected() { qCInfo(QT_CANBUS_PLUGINS_VIRTUALCAN, "Client [%p] socket connected.", this); - m_clientSocket->write("connect:can" + QByteArray::number(m_channel) + '\n'); + m_clientSocket->write(QByteArray("connect:can"_ba + QByteArray::number(m_channel) + '\n')); setState(QCanBusDevice::ConnectedState); } @@ -334,7 +315,7 @@ void VirtualCanBackend::clientReadyRead() qCDebug(QT_CANBUS_PLUGINS_VIRTUALCAN, "Client [%p] received: '%s'.", this, answer.constData()); - if (answer.startsWith("disconnect:can" + QByteArray::number(m_channel))) { + if (answer.startsWith(QByteArray("disconnect:can"_ba + QByteArray::number(m_channel)))) { m_clientSocket->disconnectFromHost(); continue; } @@ -342,7 +323,7 @@ void VirtualCanBackend::clientReadyRead() const QByteArrayList list = answer.split('#'); Q_ASSERT(list.size() == 3); - const quint32 id = list.at(0).toUInt(); + const QCanBusFrame::FrameId id = list.at(0).toUInt(); const QByteArray flags = list.at(1); const QByteArray data = QByteArray::fromHex(list.at(2)); const qint64 timeStamp = QDateTime::currentDateTime().toMSecsSinceEpoch(); diff --git a/src/plugins/canbus/virtualcan/virtualcanbackend.h b/src/plugins/canbus/virtualcan/virtualcanbackend.h index c83b568..93bae2a 100644 --- a/src/plugins/canbus/virtualcan/virtualcanbackend.h +++ b/src/plugins/canbus/virtualcan/virtualcanbackend.h @@ -1,50 +1,16 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Andre Hartmann <aha_1980@gmx.de> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Andre Hartmann <aha_1980@gmx.de> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef VIRTUALCANBACKEND_H #define VIRTUALCANBACKEND_H -#include <QtSerialBus/qcanbusframe.h> #include <QtSerialBus/qcanbusdevice.h> #include <QtSerialBus/qcanbusdeviceinfo.h> +#include <QtSerialBus/qcanbusframe.h> #include <QtCore/qlist.h> #include <QtCore/qurl.h> #include <QtCore/qvariant.h> -#include <QtCore/qvector.h> QT_BEGIN_NAMESPACE @@ -83,7 +49,7 @@ public: bool open() override; void close() override; - void setConfigurationParameter(int key, const QVariant &value) override; + void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override; bool writeFrame(const QCanBusFrame &frame) override; @@ -91,7 +57,11 @@ public: static QList<QCanBusDeviceInfo> interfaces(); + QCanBusDeviceInfo deviceInfo() const override; + private: + static QCanBusDeviceInfo virtualCanDeviceInfo(uint channel); + void clientConnected(); void clientDisconnected(); void clientReadyRead(); |