diff options
Diffstat (limited to 'src/plugins/canbus/peakcan/peakcanbackend.cpp')
-rw-r--r-- | src/plugins/canbus/peakcan/peakcanbackend.cpp | 85 |
1 files changed, 81 insertions, 4 deletions
diff --git a/src/plugins/canbus/peakcan/peakcanbackend.cpp b/src/plugins/canbus/peakcan/peakcanbackend.cpp index 6e1af1c..0b4cf5b 100644 --- a/src/plugins/canbus/peakcan/peakcanbackend.cpp +++ b/src/plugins/canbus/peakcan/peakcanbackend.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com> +** Copyright (c) 2020 Andre Hartmann <aha_1980@gmx.de> ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -46,6 +47,7 @@ #include <QtCore/qloggingcategory.h> #include <algorithm> +#include <vector> #ifdef Q_OS_WIN32 # include <QtCore/qwineventnotifier.h> @@ -64,7 +66,7 @@ Q_GLOBAL_STATIC(QLibrary, pcanLibrary) bool PeakCanBackend::canCreate(QString *errorReason) { #ifdef LINK_LIBPCANBASIC - return true; + Q_UNUSED(errorReason); #else static bool symbolsResolved = resolvePeakCanSymbols(pcanLibrary()); if (Q_UNLIKELY(!symbolsResolved)) { @@ -73,8 +75,17 @@ bool PeakCanBackend::canCreate(QString *errorReason) *errorReason = pcanLibrary()->errorString(); return false; } - return true; #endif + + char apiVersion[32]; + TPCANStatus stat = CAN_GetValue(PCAN_NONEBUS, PCAN_API_VERSION, apiVersion, sizeof(apiVersion)); + if (Q_UNLIKELY(stat != PCAN_ERROR_OK)) { + qCWarning(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot resolve PCAN-API version!"); + return false; + } + qCInfo(QT_CANBUS_PLUGINS_PEAKCAN, "Using PCAN-API version: %s", apiVersion); + + return true; } struct PcanChannel{ @@ -117,7 +128,7 @@ static const PcanChannel pcanChannels[] = { { "none", PCAN_NONEBUS } }; -QList<QCanBusDeviceInfo> PeakCanBackend::interfaces() +QList<QCanBusDeviceInfo> PeakCanBackend::interfacesByChannelCondition() { QList<QCanBusDeviceInfo> result; @@ -143,15 +154,81 @@ QList<QCanBusDeviceInfo> PeakCanBackend::interfaces() if (chnStat != PCAN_ERROR_OK) channel = 0; + QString alias; + quint32 deviceId = 0; + const TPCANStatus idStat = ::CAN_GetValue(index, PCAN_DEVICE_ID, + &deviceId, sizeof(deviceId)); + if (idStat == PCAN_ERROR_OK) + alias = QString::number(deviceId); + result.append(std::move(createDeviceInfo(QLatin1String(pcanChannels[i].name), QString(), QLatin1String(description), - channel, false, isFd))); + alias, channel, false, isFd))); + } + } + + return result; +} + +QList<QCanBusDeviceInfo> PeakCanBackend::interfacesByAttachedChannels(bool *ok) +{ + *ok = true; + quint32 count = 0; + const TPCANStatus countStat = ::CAN_GetValue(0, PCAN_ATTACHED_CHANNELS_COUNT, + &count, sizeof(count)); + if (Q_UNLIKELY(countStat != PCAN_ERROR_OK)) { + qCWarning(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot query PCAN_ATTACHED_CHANNELS_COUNT."); + *ok = false; + return {}; + } + if (count == 0) + return {}; + + std::vector<TPCANChannelInformation> infos(count); + const TPCANStatus infosStat = ::CAN_GetValue(0, PCAN_ATTACHED_CHANNELS, infos.data(), + infos.size() * sizeof(TPCANChannelInformation)); + if (Q_UNLIKELY(infosStat != PCAN_ERROR_OK)) { + qCWarning(QT_CANBUS_PLUGINS_PEAKCAN, "Cannot query PCAN_ATTACHED_CHANNELS."); + *ok = false; + return {}; + } + + QList<QCanBusDeviceInfo> result; + for (quint32 i = 0; i < count; ++i) { + auto info = infos[i]; + if (info.channel_condition & PCAN_CHANNEL_AVAILABLE) { + const quint32 deviceId = info.channel_handle; + const auto pcanChannel = std::find_if(std::begin(pcanChannels), std::end(pcanChannels), + [deviceId](PcanChannel channel) { + return channel.index == deviceId; + }); + const QString name = pcanChannel->name; + const QString description = info.device_name; + const QString alias = QString::number(info.device_id); + const int channel = info.controller_number; + const bool isCanFd = (info.device_features & FEATURE_FD_CAPABLE); + + result.append(std::move(createDeviceInfo(name, QString(), description, alias, + channel, false, isCanFd))); } } return result; } +QList<QCanBusDeviceInfo> PeakCanBackend::interfaces() +{ +#ifdef Q_OS_WIN + bool ok = false; + const QList<QCanBusDeviceInfo> attachedChannelsResult = interfacesByAttachedChannels(&ok); + if (ok) + return attachedChannelsResult; +#endif + + const QList<QCanBusDeviceInfo> result = interfacesByChannelCondition(); + return result; +} + #if defined(Q_OS_WIN32) class PeakCanReadNotifier : public QWinEventNotifier { |