summaryrefslogtreecommitdiffstats
path: root/src/plugins/canbus/peakcan/peakcanbackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/canbus/peakcan/peakcanbackend.cpp')
-rw-r--r--src/plugins/canbus/peakcan/peakcanbackend.cpp85
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
{