Add zigbee uart monitor
This commit is contained in:
parent
5e2426165c
commit
097254756e
18
debian/control
vendored
18
debian/control
vendored
@ -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.
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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();
|
||||
@ -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
|
||||
241
libnymea-zigbee/zigbeeuartadaptermonitor.cpp
Normal file
241
libnymea-zigbee/zigbeeuartadaptermonitor.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
64
libnymea-zigbee/zigbeeuartadaptermonitor.h
Normal file
64
libnymea-zigbee/zigbeeuartadaptermonitor.h
Normal 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
|
||||
Reference in New Issue
Block a user