Add zigbee uart monitor

This commit is contained in:
Simon Stürz 2020-10-28 16:53:07 +01:00
parent 5e2426165c
commit 097254756e
10 changed files with 352 additions and 112 deletions

18
debian/control vendored
View File

@ -7,12 +7,13 @@ Homepage: https://nymea.io
Vcs-Git: https://github.com/nymea/nymea-zigbee.git
Build-Depends: debhelper (>= 9.0.0),
dpkg-dev (>= 1.16.1~),
pkg-config,
qt5-default,
qt5-qmake,
qtbase5-dev,
qtbase5-dev-tools,
libqt5serialport5-dev,
libreadline-dev
libudev-dev
Package: libnymea-zigbee1
Section: libs
@ -22,8 +23,8 @@ Depends: ${shlibs:Depends},
libqt5network5,
libqt5gui5,
libqt5serialport5
Description: Qt 5 based library for Zigbee
Qt 5 based library for Zigbee.
Description: Qt 5 based library for ZigBee
Qt 5 based library for ZigBee.
Package: libnymea-zigbee-dev
@ -31,9 +32,10 @@ Section: libdevel
Architecture: any
Depends: libnymea-zigbee1 (= ${binary:Version}),
${shlibs:Depends},
${misc:Depends}
Description: Qt 5 based library for Zigbee - development files
Development files for Qt 5 based Zigbee library.
${misc:Depends},
pkg-config
Dscription: Qt 5 based library for ZigBee - development files
Development files for Qt 5 based ZigBee library.
Package: libnymea-zigbee1-dbg
@ -43,5 +45,5 @@ Section: debug
Depends: libnymea-zigbee1 (= ${binary:Version}),
${shlibs:Depends},
${misc:Depends}
Description: Qt 5 based library for Zigbee - debug symbols
Debug Symbols for Qt 5 based Zigbee library.
Description: Qt 5 based library for ZigBee - debug symbols
Debug Symbols for Qt 5 based ZigBee library.

View File

@ -3,6 +3,9 @@ include(../config.pri)
TARGET = nymea-zigbee1
TEMPLATE = lib
CONFIG += link_pkgconfig
PKGCONFIG += libudev
SOURCES += \
backends/deconz/interface/zigbeeinterfacedeconz.cpp \
backends/deconz/interface/zigbeeinterfacedeconzreply.cpp \
@ -31,7 +34,6 @@ SOURCES += \
zdo/zigbeedeviceobject.cpp \
zdo/zigbeedeviceobjectreply.cpp \
zdo/zigbeedeviceprofile.cpp \
zigbeeadapter.cpp \
zigbeeadpu.cpp \
zigbeebridgecontroller.cpp \
zigbeechannelmask.cpp \
@ -47,17 +49,11 @@ SOURCES += \
zigbeenetworkrequest.cpp \
zigbeenodeendpoint.cpp \
zigbeesecurityconfiguration.cpp \
zigbeeuartadapter.cpp \
zigbeeuartadaptermonitor.cpp \
zigbeeutils.cpp \
zigbeenode.cpp \
zigbeeaddress.cpp \
# nxp/interface/zigbeeinterface.cpp \
# nxp/interface/zigbeeinterfacemessage.cpp \
# nxp/interface/zigbeeinterfacerequest.cpp \
# nxp/interface/zigbeeinterfacereply.cpp \
# nxp/zigbeenetworknxp.cpp \
# nxp/zigbeebridgecontrollernxp.cpp \
# nxp/zigbeenodeendpointnxp.cpp \
# nxp/zigbeenodenxp.cpp \
zigbeeaddress.cpp
HEADERS += \
backends/deconz/interface/deconz.h \
@ -89,7 +85,6 @@ HEADERS += \
zdo/zigbeedeviceobject.h \
zdo/zigbeedeviceobjectreply.h \
zdo/zigbeedeviceprofile.h \
zigbeeadapter.h \
zigbeeadpu.h \
zigbeebridgecontroller.h \
zigbeechannelmask.h \
@ -105,17 +100,11 @@ HEADERS += \
zigbeenetworkrequest.h \
zigbeenodeendpoint.h \
zigbeesecurityconfiguration.h \
zigbeeuartadapter.h \
zigbeeuartadaptermonitor.h \
zigbeeutils.h \
zigbeenode.h \
zigbeeaddress.h \
# nxp/interface/zigbeeinterface.h \
# nxp/interface/zigbeeinterfacemessage.h \
# nxp/interface/zigbeeinterfacerequest.h \
# nxp/interface/zigbeeinterfacereply.h \
# nxp/zigbeenetworknxp.h \
# nxp/zigbeebridgecontrollernxp.h \
# nxp/zigbeenodeendpointnxp.h \
# nxp/zigbeenodenxp.h \
zigbeeaddress.h
# install header file with relative subdirectory
for (header, HEADERS) {

View File

@ -35,6 +35,7 @@ Q_LOGGING_CATEGORY(dcZigbeeEndpoint, "ZigbeeEndpoint")
Q_LOGGING_CATEGORY(dcZigbeeInterface, "ZigbeeInterface")
Q_LOGGING_CATEGORY(dcZigbeeController, "ZigbeeController")
Q_LOGGING_CATEGORY(dcZigbeeDeviceObject, "ZigbeeDeviceObject")
Q_LOGGING_CATEGORY(dcZigbeeAdapterMonitor, "ZigbeeAdapterMonitor")
Q_LOGGING_CATEGORY(dcZigbeeClusterLibrary, "ZigbeeClusterLibrary")
Q_LOGGING_CATEGORY(dcZigbeeNetworkDatabase, "ZigbeeNetworkDatabase")
Q_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic, "ZigbeeInterfaceTraffic")

View File

@ -39,6 +39,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcZigbeeEndpoint)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterface)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeController)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeDeviceObject)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeAdapterMonitor)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeClusterLibrary)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeNetworkDatabase)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic)

View File

@ -32,58 +32,6 @@
#include "backends/deconz/zigbeenetworkdeconz.h"
#include <QDateTime>
#include <QSerialPortInfo>
QList<ZigbeeAdapter> ZigbeeNetworkManager::availableAdapters()
{
QList<ZigbeeAdapter> adapters;
qCDebug(dcZigbeeNetwork()) << "Loading available adapters" ;
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
qCDebug(dcZigbeeNetwork()) << "Adapter candidate" << serialPortInfo.portName();
qCDebug(dcZigbeeNetwork()) << " Description:" << serialPortInfo.description();
qCDebug(dcZigbeeNetwork()) << " System location:" << serialPortInfo.systemLocation();
qCDebug(dcZigbeeNetwork()) << " Manufacturer:" << serialPortInfo.manufacturer();
qCDebug(dcZigbeeNetwork()) << " Serialnumber:" << serialPortInfo.serialNumber();
if (serialPortInfo.hasProductIdentifier()) {
qCDebug(dcZigbeeNetwork()) << " Product identifier:" << serialPortInfo.productIdentifier();
}
if (serialPortInfo.hasVendorIdentifier()) {
qCDebug(dcZigbeeNetwork()) << " Vendor identifier:" << serialPortInfo.vendorIdentifier();
}
// Check if we recognize this controller
ZigbeeAdapter adapter;
if (serialPortInfo.portName().isEmpty()) {
adapter.setName("Zigbee adapter");
} else {
adapter.setName(serialPortInfo.portName());
}
if (serialPortInfo.description().isEmpty()) {
adapter.setDescription("Unknown");
} else {
adapter.setDescription(serialPortInfo.description());
}
adapter.setSystemLocation(serialPortInfo.systemLocation());
// Check if we recognize this adapter from USB information
if (serialPortInfo.manufacturer().toLower().contains("dresden elektronik")) {
adapter.setBackendSuggestionAvailable(true);
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeDeconz);
adapter.setSuggestedBaudRate(38400);
} else if (serialPortInfo.manufacturer().toLower().contains("nxp")) {
adapter.setBackendSuggestionAvailable(true);
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeNxp);
adapter.setSuggestedBaudRate(115200);
}
adapters.append(adapter);
}
return adapters;
}
QStringList ZigbeeNetworkManager::availableZigbeeBackendTypes()
{

View File

@ -30,14 +30,14 @@
#include <QObject>
#include "zigbeeadapter.h"
#include "zigbeeuartadapter.h"
#include "zigbeenetwork.h"
class ZigbeeNetworkManager
{
Q_GADGET
public:
static QList<ZigbeeAdapter> availableAdapters();
static QStringList availableZigbeeBackendTypes();
static ZigbeeNetwork *createZigbeeNetwork(Zigbee::ZigbeeBackendType backend, QObject *parent = nullptr);
};

View File

@ -25,76 +25,76 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zigbeeadapter.h"
#include "zigbeeuartadapter.h"
ZigbeeAdapter::ZigbeeAdapter()
ZigbeeUartAdapter::ZigbeeUartAdapter()
{
}
QString ZigbeeAdapter::name() const
QString ZigbeeUartAdapter::name() const
{
return m_name;
}
void ZigbeeAdapter::setName(const QString &name)
void ZigbeeUartAdapter::setName(const QString &name)
{
m_name = name;
}
QString ZigbeeAdapter::description() const
QString ZigbeeUartAdapter::description() const
{
return m_description;
}
void ZigbeeAdapter::setDescription(const QString &description)
void ZigbeeUartAdapter::setDescription(const QString &description)
{
m_description = description;
}
QString ZigbeeAdapter::systemLocation() const
QString ZigbeeUartAdapter::systemLocation() const
{
return m_systemLocation;
}
void ZigbeeAdapter::setSystemLocation(const QString &systemLocation)
void ZigbeeUartAdapter::setSystemLocation(const QString &systemLocation)
{
m_systemLocation = systemLocation;
}
bool ZigbeeAdapter::backendSuggestionAvailable() const
bool ZigbeeUartAdapter::backendSuggestionAvailable() const
{
return m_backendSuggestionAvailable;
}
void ZigbeeAdapter::setBackendSuggestionAvailable(bool backendSuggestionAvailable)
void ZigbeeUartAdapter::setBackendSuggestionAvailable(bool backendSuggestionAvailable)
{
m_backendSuggestionAvailable = backendSuggestionAvailable;
}
Zigbee::ZigbeeBackendType ZigbeeAdapter::suggestedZigbeeBackendType() const
Zigbee::ZigbeeBackendType ZigbeeUartAdapter::suggestedZigbeeBackendType() const
{
return m_suggestedZigbeeBackendType;
}
void ZigbeeAdapter::setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendType backendType)
void ZigbeeUartAdapter::setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendType backendType)
{
m_suggestedZigbeeBackendType = backendType;
}
qint32 ZigbeeAdapter::suggestedBaudRate() const
qint32 ZigbeeUartAdapter::suggestedBaudRate() const
{
return m_suggestedBaudRate;
}
void ZigbeeAdapter::setSuggestedBaudRate(qint32 baudRate)
void ZigbeeUartAdapter::setSuggestedBaudRate(qint32 baudRate)
{
m_suggestedBaudRate = baudRate;
}
QDebug operator<<(QDebug debug, const ZigbeeAdapter &adapter)
QDebug operator<<(QDebug debug, const ZigbeeUartAdapter &adapter)
{
debug.nospace() << "ZigbeeAdapter(" << adapter.name() << " - " << adapter.description();
debug.nospace() << "ZigbeeUartAdapter(" << adapter.name() << " - " << adapter.description();
debug.nospace() << ", " << adapter.systemLocation();
if (adapter.backendSuggestionAvailable()) {
debug.nospace() << "Suggested backend: " << adapter.suggestedZigbeeBackendType();

View File

@ -25,26 +25,18 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZIGBEEADAPTER_H
#define ZIGBEEADAPTER_H
#ifndef ZIGBEEUARTADAPTER_H
#define ZIGBEEUARTADAPTER_H
#include <QObject>
#include <QString>
#include <QDebug>
#include "zigbee.h"
class ZigbeeAdapter
class ZigbeeUartAdapter
{
Q_GADGET
Q_PROPERTY(QString name READ name)
Q_PROPERTY(QString description READ description)
Q_PROPERTY(QString systemLocation READ systemLocation)
Q_PROPERTY(bool backendSuggestionAvailable READ backendSuggestionAvailable)
Q_PROPERTY(Zigbee::ZigbeeBackendType suggestedZigbeeBackendType READ suggestedZigbeeBackendType)
Q_PROPERTY(qint32 suggestedBaudRate READ suggestedBaudRate)
public:
explicit ZigbeeAdapter();
explicit ZigbeeUartAdapter();
QString name() const;
void setName(const QString &name);
@ -74,7 +66,9 @@ private:
qint32 m_suggestedBaudRate = 38400;
};
QDebug operator<<(QDebug debug, const ZigbeeAdapter &adapter);
Q_DECLARE_METATYPE(ZigbeeUartAdapter)
QDebug operator<<(QDebug debug, const ZigbeeUartAdapter &adapter);
#endif // ZIGBEEADAPTER_H

View File

@ -0,0 +1,241 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea-zigbee.
* This project including source code and documentation is protected by copyright law, and
* remains the property of nymea GmbH. All rights, including reproduction, publication,
* editing and translation, are reserved. The use of this project is subject to the terms of a
* license agreement to be concluded with nymea GmbH in accordance with the terms
* of use of nymea GmbH, available under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation; version 3.
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this project.
* If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under contact@nymea.io
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zigbeeuartadaptermonitor.h"
#include "loggingcategory.h"
#include <QSerialPortInfo>
ZigbeeUartAdapterMonitor::ZigbeeUartAdapterMonitor(QObject *parent) : QObject(parent)
{
qRegisterMetaType<ZigbeeUartAdapter>();
m_udev = udev_new();
if (!m_udev) {
qCWarning(dcZigbeeAdapterMonitor()) << "Could not initialize udev for the adapter monitor";
return;
}
// Read initially all tty devices
struct udev_enumerate *enumerate = udev_enumerate_new(m_udev);
if (!enumerate) {
qCWarning(dcZigbeeAdapterMonitor()) << "Could not create udev enumerate for initial device reading for the adapter monitor.";
udev_unref(m_udev);
m_udev = nullptr;
return;
}
udev_enumerate_add_match_subsystem(enumerate, "tty");
if (udev_enumerate_scan_devices(enumerate) < 0) {
qCWarning(dcZigbeeAdapterMonitor()) << "Failed to scan devices from udev enumerate.";
udev_enumerate_unref(enumerate);
enumerate = nullptr;
udev_unref(m_udev);
m_udev = nullptr;
return;
}
qCDebug(dcZigbeeAdapterMonitor()) << "Load initial list of available serial ports...";
struct udev_list_entry *devices = nullptr;
devices = udev_enumerate_get_list_entry(enumerate);
struct udev_list_entry *dev_list_entry = nullptr;
udev_list_entry_foreach(dev_list_entry, devices) {
struct udev_device *device = nullptr;
const char *path;
path = udev_list_entry_get_name(dev_list_entry);
device = udev_device_new_from_syspath(m_udev, path);
// Print properties
struct udev_list_entry *properties = udev_device_get_properties_list_entry(device);
struct udev_list_entry *property_list_entry = nullptr;
udev_list_entry_foreach(property_list_entry, properties) {
qCDebug(dcZigbeeAdapterMonitor()) << " - Property" << udev_list_entry_get_name(property_list_entry) << udev_list_entry_get_value(property_list_entry);
}
QString devicePath = QString::fromLatin1(udev_device_get_property_value(device,"DEVNAME"));
QString manufacturerString = QString::fromLatin1(udev_device_get_property_value(device,"ID_VENDOR_ENC"));
QString descriptionString = QString::fromLatin1(udev_device_get_property_value(device,"ID_MODEL_ENC"));
QString serialNumberString = QString::fromLatin1(udev_device_get_property_value(device, "ID_SERIAL_SHORT"));
// Clean up this device since we have all information
udev_device_unref(device);
qCDebug(dcZigbeeAdapterMonitor()) << "[+]" << devicePath << manufacturerString << descriptionString << serialNumberString;
addAdapterInternally(devicePath);
}
udev_enumerate_unref(enumerate);
enumerate = nullptr;
// Create udev monitor
m_monitor = udev_monitor_new_from_netlink(m_udev, "udev");
if (!m_monitor) {
qCWarning(dcZigbeeAdapterMonitor()) << "Could not initialize udev monitor.";
udev_unref(m_udev);
m_udev = nullptr;
return;
}
// Set monitor filter to tty subsystem
if (udev_monitor_filter_add_match_subsystem_devtype(m_monitor, "tty", nullptr) < 0) {
qCWarning(dcZigbeeAdapterMonitor()) << "Could not set subsystem device type filter to tty.";
udev_monitor_unref(m_monitor);
m_monitor = nullptr;
udev_unref(m_udev);
m_udev = nullptr;
return;
}
// Enable the monitor
if (udev_monitor_enable_receiving(m_monitor) < 0) {
qCWarning(dcZigbeeAdapterMonitor()) << "Could not enable udev monitor.";
udev_monitor_unref(m_monitor);
m_monitor = nullptr;
udev_unref(m_udev);
m_udev = nullptr;
return;
}
// Create socket notifier for read
int socketDescriptor = udev_monitor_get_fd(m_monitor);
m_notifier = new QSocketNotifier(socketDescriptor, QSocketNotifier::Read, this);
connect(m_notifier, &QSocketNotifier::activated, this, [this, socketDescriptor](int socket){
// Make sure the socket matches
if (socketDescriptor != socket) {
qCWarning(dcZigbeeAdapterMonitor()) << "socket != socketdescriptor";
return;
}
// Create udev device
udev_device *device = udev_monitor_receive_device(m_monitor);
if (!device) {
qCWarning(dcZigbeeAdapterMonitor()) << "Got socket sotification but could not read device information.";
return;
}
QString actionString = QString::fromLatin1(udev_device_get_action(device));
QString devicePath = QString::fromLatin1(udev_device_get_property_value(device,"DEVNAME"));
QString manufacturerString = QString::fromLatin1(udev_device_get_property_value(device,"ID_VENDOR_ENC"));
QString descriptionString = QString::fromLatin1(udev_device_get_property_value(device,"ID_MODEL_ENC"));
QString serialNumberString = QString::fromLatin1(udev_device_get_property_value(device, "ID_SERIAL_SHORT"));
// Clean udev device
udev_device_unref(device);
// Make sure we know the action
if (actionString.isEmpty())
return;
if (actionString == "add") {
qCDebug(dcZigbeeAdapterMonitor()) << "[+]" << devicePath << serialNumberString;
if (!m_availableAdapters.contains(devicePath)) {
addAdapterInternally(devicePath);
}
}
if (actionString == "remove") {
qCDebug(dcZigbeeAdapterMonitor()) << "[-]" << devicePath << serialNumberString;
if (m_availableAdapters.contains(devicePath)) {
ZigbeeUartAdapter adapter = m_availableAdapters.take(devicePath);
qCDebug(dcZigbeeAdapterMonitor()) << "Removed" << adapter;
emit adapterRemoved(adapter);
}
}
});
m_notifier->setEnabled(true);
m_isValid = true;
}
QList<ZigbeeUartAdapter> ZigbeeUartAdapterMonitor::availableAdapters() const
{
return m_availableAdapters.values();
}
bool ZigbeeUartAdapterMonitor::isValid() const
{
return m_isValid;
}
void ZigbeeUartAdapterMonitor::addAdapterInternally(const QString &systemLocation)
{
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
if (serialPortInfo.systemLocation() != systemLocation)
continue;
if (m_availableAdapters.keys().contains(systemLocation)) {
qCWarning(dcZigbeeAdapterMonitor()) << "The adapter" << systemLocation << "has already been added to the monitor.";
continue;
}
qCDebug(dcZigbeeAdapterMonitor()) << "Adapter candidate" << serialPortInfo.portName();
qCDebug(dcZigbeeAdapterMonitor()) << " Description:" << serialPortInfo.description();
qCDebug(dcZigbeeAdapterMonitor()) << " System location:" << serialPortInfo.systemLocation();
qCDebug(dcZigbeeAdapterMonitor()) << " Manufacturer:" << serialPortInfo.manufacturer();
qCDebug(dcZigbeeAdapterMonitor()) << " Serialnumber:" << serialPortInfo.serialNumber();
if (serialPortInfo.hasProductIdentifier()) {
qCDebug(dcZigbeeAdapterMonitor()) << " Product identifier:" << serialPortInfo.productIdentifier();
}
if (serialPortInfo.hasVendorIdentifier()) {
qCDebug(dcZigbeeAdapterMonitor()) << " Vendor identifier:" << serialPortInfo.vendorIdentifier();
}
// Check if we recognize this controller
ZigbeeUartAdapter adapter;
if (serialPortInfo.portName().isEmpty()) {
adapter.setName("Zigbee adapter");
} else {
adapter.setName(serialPortInfo.portName());
}
if (serialPortInfo.description().isEmpty()) {
adapter.setDescription("Unknown");
} else {
adapter.setDescription(serialPortInfo.description());
}
adapter.setSystemLocation(serialPortInfo.systemLocation());
// Check if we recognize this adapter from USB information
if (serialPortInfo.manufacturer().toLower().contains("dresden elektronik")) {
adapter.setBackendSuggestionAvailable(true);
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeDeconz);
adapter.setSuggestedBaudRate(38400);
} else if (serialPortInfo.manufacturer().toLower().contains("nxp")) {
adapter.setBackendSuggestionAvailable(true);
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeNxp);
adapter.setSuggestedBaudRate(115200);
}
qCDebug(dcZigbeeAdapterMonitor()) << "Added" << adapter;
m_availableAdapters.insert(adapter.systemLocation(), adapter);
emit adapterAdded(adapter);
}
}

View File

@ -0,0 +1,64 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea-zigbee.
* This project including source code and documentation is protected by copyright law, and
* remains the property of nymea GmbH. All rights, including reproduction, publication,
* editing and translation, are reserved. The use of this project is subject to the terms of a
* license agreement to be concluded with nymea GmbH in accordance with the terms
* of use of nymea GmbH, available under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation; version 3.
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this project.
* If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under contact@nymea.io
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZIGBEEUARTADAPTERMONITOR_H
#define ZIGBEEUARTADAPTERMONITOR_H
#include <QObject>
#include <QSocketNotifier>
#include <libudev.h>
#include "zigbeeuartadapter.h"
class ZigbeeUartAdapterMonitor : public QObject
{
Q_OBJECT
public:
explicit ZigbeeUartAdapterMonitor(QObject *parent = nullptr);
QList<ZigbeeUartAdapter> availableAdapters() const;
bool isValid() const;
private:
bool m_isValid = false;
struct udev *m_udev = nullptr;
struct udev_monitor *m_monitor = nullptr;
QSocketNotifier *m_notifier = nullptr;
QHash<QString, ZigbeeUartAdapter> m_availableAdapters;
void addAdapterInternally(const QString &systemLocation);
signals:
void adapterAdded(const ZigbeeUartAdapter &adapter);
void adapterRemoved(const ZigbeeUartAdapter &adapter);
};
#endif // ZIGBEEUARTADAPTERMONITOR_H