diff options
author | Andre Hartmann <aha_1980@gmx.de> | 2016-07-31 20:43:13 +0200 |
---|---|---|
committer | André Hartmann <aha_1980@gmx.de> | 2017-01-10 15:18:02 +0000 |
commit | 55d405697c79c4ca23535140e60915e89b4054e3 (patch) | |
tree | 8144ae742df62f6d362a71d160a2e3e93484fd96 /src/plugins/canbus/socketcan/socketcanbackend.cpp | |
parent | 66fd2b9655d5f34f880b8daf8b2f422a27789517 (diff) |
CAN: Add QCanBusDeviceInfo
Returns:
* a list of available devices for the chosen plugin
* if the device is virtual
* if the device is CAN FD capable
Use this list in the CAN Example for interface selection.
If information about virtual channels or CAN FD capabability is not
available, false is returned.
For SocketCAN, PeakCAN, VectorCAN and SystecCAN, the implementation is
completed. TinyCAN only return the list of possible interfaces for now.
This is can be changed later, but needs quite some refactoring of the
TinyCAN plugin.
[ChangeLog][QtCanBus] Added the new class QCanBusDeviceInfo
for enumeration of available CAN interfaces and more information
about them.
Task-number: QTBUG-54298
Change-Id: I851bcc3b9ee41aaaf1164c6b4a5aaf6503cd8746
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/plugins/canbus/socketcan/socketcanbackend.cpp')
-rw-r--r-- | src/plugins/canbus/socketcan/socketcanbackend.cpp | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/plugins/canbus/socketcan/socketcanbackend.cpp b/src/plugins/canbus/socketcan/socketcanbackend.cpp index 8974279..c506706 100644 --- a/src/plugins/canbus/socketcan/socketcanbackend.cpp +++ b/src/plugins/canbus/socketcan/socketcanbackend.cpp @@ -36,8 +36,10 @@ #include "socketcanbackend.h" -#include <QtCore/qdebug.h> #include <QtCore/qdatastream.h> +#include <QtCore/qdebug.h> +#include <QtCore/qdiriterator.h> +#include <QtCore/qfile.h> #include <QtCore/qsocketnotifier.h> #include <linux/can/error.h> @@ -74,6 +76,71 @@ struct canfd_frame { QT_BEGIN_NAMESPACE +const char sysClassNetC[] = "/sys/class/net/"; +const char flagsC[] = "/flags"; +const char mtuC[] = "/mtu"; +const char typeC[] = "/type"; +const char virtualC[] = "virtual"; + +enum { + CanFlexibleDataRateMtu = 72, + TypeSocketCan = 280, + DeviceIsActive = 1 +}; + +static QByteArray fileContent(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + return QByteArray(); + + return file.readAll().trimmed(); +} + +static bool isFlexibleDataRateCapable(const QString &canDevice) +{ + const QString path = QLatin1String(sysClassNetC) + canDevice + QLatin1String(mtuC); + const int mtu = fileContent(path).toInt(); + return mtu == CanFlexibleDataRateMtu; +} + +static bool isVirtual(const QString &canDevice) +{ + const QFileInfo fi(QLatin1String(sysClassNetC) + canDevice); + return fi.canonicalPath().contains(QLatin1String(virtualC)); +} + +static quint32 flags(const QString &canDevice) +{ + const QString path = QLatin1String(sysClassNetC) + canDevice + QLatin1String(flagsC); + const quint32 result = fileContent(path).toUInt(nullptr, 0); + return result; +} + +QList<QCanBusDeviceInfo> SocketCanBackend::interfaces() +{ + QList<QCanBusDeviceInfo> result; + QDirIterator it(sysClassNetC, + QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, + QDirIterator::Subdirectories); + + while (it.hasNext()) { + const QString dirEntry = it.next(); + if (fileContent(dirEntry + QLatin1String(typeC)).toInt() != TypeSocketCan) + continue; + + const QString deviceName = dirEntry.mid(strlen(sysClassNetC)); + if (!(flags(deviceName) & DeviceIsActive)) + continue; + + auto info = createDeviceInfo(deviceName, isVirtual(deviceName), + isFlexibleDataRateCapable(deviceName)); + result.append(info); + } + + return result; +} + SocketCanBackend::SocketCanBackend(const QString &name) : canSocket(-1), notifier(nullptr), |