Make basic network start working
This commit is contained in:
parent
a8c1fe9b9f
commit
128763b5cc
BIN
docs/JN-UG-3113.pdf
Normal file
BIN
docs/JN-UG-3113.pdf
Normal file
Binary file not shown.
BIN
docs/deCONZ-Serial-Protocol-en.pdf
Normal file
BIN
docs/deCONZ-Serial-Protocol-en.pdf
Normal file
Binary file not shown.
BIN
docs/docs-05-3474-20-0csg-zigbee-specification.pdf
Normal file
BIN
docs/docs-05-3474-20-0csg-zigbee-specification.pdf
Normal file
Binary file not shown.
@ -3,11 +3,13 @@
|
|||||||
#include "zigbeeutils.h"
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
ZigbeeInterface::ZigbeeInterface(QObject *parent) :
|
ZigbeeInterface::ZigbeeInterface(QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent)
|
||||||
m_serialPort(nullptr),
|
|
||||||
m_readingState(WaitForStart)
|
|
||||||
{
|
{
|
||||||
|
m_reconnectTimer = new QTimer(this);
|
||||||
|
m_reconnectTimer->setSingleShot(true);
|
||||||
|
m_reconnectTimer->setInterval(5000);
|
||||||
|
|
||||||
|
connect(m_reconnectTimer, &QTimer::timeout, this, &ZigbeeInterface::onReconnectTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeInterface::~ZigbeeInterface()
|
ZigbeeInterface::~ZigbeeInterface()
|
||||||
@ -56,13 +58,24 @@ void ZigbeeInterface::streamByte(quint8 byte, bool specialCharacter)
|
|||||||
|
|
||||||
byte ^= 0x10;
|
byte ^= 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeInterfaceTraffic()) << "[out]" << ZigbeeUtils::convertByteToHexString(byte);
|
qCDebug(dcZigbeeInterfaceTraffic()) << "[out]" << ZigbeeUtils::convertByteToHexString(byte);
|
||||||
if (m_serialPort->write(QByteArray(1, (char)byte)) < 0) {
|
if (m_serialPort->write(QByteArray(1, static_cast<char>(byte))) < 0) {
|
||||||
qCWarning(dcZigbeeInterface()) << "Could not stream byte" << ZigbeeUtils::convertByteToHexString(byte);
|
qCWarning(dcZigbeeInterface()) << "Could not stream byte" << ZigbeeUtils::convertByteToHexString(byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_serialPort->flush();
|
m_serialPort->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeInterface::setAvailable(bool available)
|
||||||
|
{
|
||||||
|
if (m_available == available)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_available = available;
|
||||||
|
emit availableChanged(m_available);
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeInterface::setReadingState(const ZigbeeInterface::ReadingState &state)
|
void ZigbeeInterface::setReadingState(const ZigbeeInterface::ReadingState &state)
|
||||||
{
|
{
|
||||||
if (m_readingState == state)
|
if (m_readingState == state)
|
||||||
@ -72,6 +85,19 @@ void ZigbeeInterface::setReadingState(const ZigbeeInterface::ReadingState &state
|
|||||||
qCDebug(dcZigbeeInterfaceTraffic()) << m_readingState;
|
qCDebug(dcZigbeeInterfaceTraffic()) << m_readingState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeInterface::onReconnectTimeout()
|
||||||
|
{
|
||||||
|
if (m_serialPort && !m_serialPort->isOpen()) {
|
||||||
|
if (!m_serialPort->open(QSerialPort::ReadWrite)) {
|
||||||
|
setAvailable(false);
|
||||||
|
m_reconnectTimer->start();
|
||||||
|
} else {
|
||||||
|
qCDebug(dcZigbeeInterface()) << "The controller showed up again.";
|
||||||
|
setAvailable(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeInterface::onReadyRead()
|
void ZigbeeInterface::onReadyRead()
|
||||||
{
|
{
|
||||||
QByteArray data = m_serialPort->readAll();
|
QByteArray data = m_serialPort->readAll();
|
||||||
@ -159,8 +185,11 @@ void ZigbeeInterface::onReadyRead()
|
|||||||
|
|
||||||
void ZigbeeInterface::onError(const QSerialPort::SerialPortError &error)
|
void ZigbeeInterface::onError(const QSerialPort::SerialPortError &error)
|
||||||
{
|
{
|
||||||
if (error != QSerialPort::NoError) {
|
if (error != QSerialPort::NoError && m_serialPort->isOpen()) {
|
||||||
qCWarning(dcZigbeeInterface()) << "Serial port error:" << error << m_serialPort->errorString();
|
qCCritical(dcZigbeeInterface()) << "Serial port error:" << error << m_serialPort->errorString();
|
||||||
|
m_reconnectTimer->start();
|
||||||
|
m_serialPort->close();
|
||||||
|
setAvailable(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +200,8 @@ bool ZigbeeInterface::enable(const QString &serialPort, qint32 baudrate)
|
|||||||
m_serialPort = nullptr;
|
m_serialPort = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setAvailable(false);
|
||||||
|
|
||||||
m_serialPort = new QSerialPort(serialPort, this);
|
m_serialPort = new QSerialPort(serialPort, this);
|
||||||
m_serialPort->setBaudRate(baudrate);
|
m_serialPort->setBaudRate(baudrate);
|
||||||
m_serialPort->setDataBits(QSerialPort::Data8);
|
m_serialPort->setDataBits(QSerialPort::Data8);
|
||||||
@ -182,12 +213,12 @@ bool ZigbeeInterface::enable(const QString &serialPort, qint32 baudrate)
|
|||||||
|
|
||||||
if (!m_serialPort->open(QSerialPort::ReadWrite)) {
|
if (!m_serialPort->open(QSerialPort::ReadWrite)) {
|
||||||
qCWarning(dcZigbeeInterface()) << "Could not open serial port" << serialPort << baudrate;
|
qCWarning(dcZigbeeInterface()) << "Could not open serial port" << serialPort << baudrate;
|
||||||
delete m_serialPort;
|
m_reconnectTimer->start();
|
||||||
m_serialPort = nullptr;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeInterface()) << "Interface enabled successfully on" << serialPort;
|
qCDebug(dcZigbeeInterface()) << "Interface enabled successfully on" << serialPort;
|
||||||
|
setAvailable(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +239,6 @@ void ZigbeeInterface::sendMessage(const ZigbeeInterfaceMessage &message)
|
|||||||
{
|
{
|
||||||
quint16 messageTypeValue = static_cast<quint16>(message.messageType());
|
quint16 messageTypeValue = static_cast<quint16>(message.messageType());
|
||||||
quint16 lengthValue = static_cast<quint16>(message.data().count());
|
quint16 lengthValue = static_cast<quint16>(message.data().count());
|
||||||
|
|
||||||
quint8 crcValue = calculateCrc(messageTypeValue, lengthValue, message.data());
|
quint8 crcValue = calculateCrc(messageTypeValue, lengthValue, message.data());
|
||||||
|
|
||||||
qCDebug(dcZigbeeInterface()) << "-->" << message << "|" << "crc:" << ZigbeeUtils::convertByteToHexString(crcValue) << ", length:" << ZigbeeUtils::convertUint16ToHexString(lengthValue);
|
qCDebug(dcZigbeeInterface()) << "-->" << message << "|" << "crc:" << ZigbeeUtils::convertByteToHexString(crcValue) << ", length:" << ZigbeeUtils::convertUint16ToHexString(lengthValue);
|
||||||
@ -221,7 +251,7 @@ void ZigbeeInterface::sendMessage(const ZigbeeInterfaceMessage &message)
|
|||||||
streamByte(crcValue);
|
streamByte(crcValue);
|
||||||
|
|
||||||
for (int i = 0; i < message.data().count(); i++) {
|
for (int i = 0; i < message.data().count(); i++) {
|
||||||
streamByte(message.data().at(i));
|
streamByte(static_cast<quint8>(message.data().at(i)));
|
||||||
}
|
}
|
||||||
streamByte(0x03, true);
|
streamByte(0x03, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define ZIGBEEINTERFACE_H
|
#define ZIGBEEINTERFACE_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
#include <QSerialPort>
|
#include <QSerialPort>
|
||||||
|
|
||||||
#include "zigbee.h"
|
#include "zigbee.h"
|
||||||
@ -29,11 +30,13 @@ public:
|
|||||||
QString serialPort() const;
|
QString serialPort() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSerialPort *m_serialPort;
|
QTimer *m_reconnectTimer = nullptr;
|
||||||
|
QSerialPort *m_serialPort = nullptr;
|
||||||
QByteArray m_messageBuffer;
|
QByteArray m_messageBuffer;
|
||||||
|
bool m_available = false;
|
||||||
|
|
||||||
// Message parsing
|
// Message parsing
|
||||||
ReadingState m_readingState;
|
ReadingState m_readingState = WaitForStart;
|
||||||
quint8 m_crcValue;
|
quint8 m_crcValue;
|
||||||
quint8 m_currentValue;
|
quint8 m_currentValue;
|
||||||
quint16 m_messageTypeValue;
|
quint16 m_messageTypeValue;
|
||||||
@ -44,14 +47,15 @@ private:
|
|||||||
quint8 calculateCrc(const quint16 &messageTypeValue, const quint16 &lenghtValue, const QByteArray &data);
|
quint8 calculateCrc(const quint16 &messageTypeValue, const quint16 &lenghtValue, const QByteArray &data);
|
||||||
|
|
||||||
void streamByte(quint8 byte, bool specialCharacter = false);
|
void streamByte(quint8 byte, bool specialCharacter = false);
|
||||||
|
void setAvailable(bool available);
|
||||||
void setReadingState(const ReadingState & state);
|
void setReadingState(const ReadingState & state);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void availableChanged(const bool &available);
|
void availableChanged(bool available);
|
||||||
void messageReceived(const ZigbeeInterfaceMessage &message);
|
void messageReceived(const ZigbeeInterfaceMessage &message);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void onReconnectTimeout();
|
||||||
void onReadyRead();
|
void onReadyRead();
|
||||||
void onError(const QSerialPort::SerialPortError &error);
|
void onError(const QSerialPort::SerialPortError &error);
|
||||||
|
|
||||||
|
|||||||
@ -10,10 +10,13 @@ SOURCES += \
|
|||||||
interface/zigbeeinterfacemessage.cpp \
|
interface/zigbeeinterfacemessage.cpp \
|
||||||
interface/zigbeeinterfacerequest.cpp \
|
interface/zigbeeinterfacerequest.cpp \
|
||||||
interface/zigbeeinterfacereply.cpp \
|
interface/zigbeeinterfacereply.cpp \
|
||||||
|
nxp/nxpzigbeenetworkmanager.cpp \
|
||||||
|
zigbeenetwork.cpp \
|
||||||
zigbeenetworkmanager.cpp \
|
zigbeenetworkmanager.cpp \
|
||||||
zigbee.cpp \
|
zigbee.cpp \
|
||||||
loggingcategory.cpp \
|
loggingcategory.cpp \
|
||||||
zigbeebridgecontroller.cpp \
|
zigbeebridgecontroller.cpp \
|
||||||
|
zigbeesecurityconfiguration.cpp \
|
||||||
zigbeeutils.cpp \
|
zigbeeutils.cpp \
|
||||||
zigbeenode.cpp \
|
zigbeenode.cpp \
|
||||||
zigbeeaddress.cpp \
|
zigbeeaddress.cpp \
|
||||||
@ -23,10 +26,13 @@ HEADERS += \
|
|||||||
interface/zigbeeinterfacemessage.h \
|
interface/zigbeeinterfacemessage.h \
|
||||||
interface/zigbeeinterfacerequest.h \
|
interface/zigbeeinterfacerequest.h \
|
||||||
interface/zigbeeinterfacereply.h \
|
interface/zigbeeinterfacereply.h \
|
||||||
|
nxp/nxpzigbeenetworkmanager.h \
|
||||||
|
zigbeenetwork.h \
|
||||||
zigbeenetworkmanager.h \
|
zigbeenetworkmanager.h \
|
||||||
zigbee.h \
|
zigbee.h \
|
||||||
loggingcategory.h \
|
loggingcategory.h \
|
||||||
zigbeebridgecontroller.h \
|
zigbeebridgecontroller.h \
|
||||||
|
zigbeesecurityconfiguration.h \
|
||||||
zigbeeutils.h \
|
zigbeeutils.h \
|
||||||
zigbeenode.h \
|
zigbeenode.h \
|
||||||
zigbeeaddress.h \
|
zigbeeaddress.h \
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#include "loggingcategory.h"
|
#include "loggingcategory.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(dcZigbee, "Zigbee")
|
Q_LOGGING_CATEGORY(dcZigbeeNetwork, "ZigbeeNetwork")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeInterface, "ZigbeeInterface")
|
Q_LOGGING_CATEGORY(dcZigbeeInterface, "ZigbeeInterface")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeController, "ZigbeeController")
|
Q_LOGGING_CATEGORY(dcZigbeeController, "ZigbeeController")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic, "ZigbeeInterfaceTraffic")
|
Q_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic, "ZigbeeInterfaceTraffic")
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbee)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeNetwork)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterface)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterface)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeController)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeController)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic)
|
||||||
|
|||||||
6
libnymea-zigbee/nxp/nxpzigbeenetworkmanager.cpp
Normal file
6
libnymea-zigbee/nxp/nxpzigbeenetworkmanager.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "nxpzigbeenetworkmanager.h"
|
||||||
|
|
||||||
|
NxpZigbeeNetworkManager::NxpZigbeeNetworkManager(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
17
libnymea-zigbee/nxp/nxpzigbeenetworkmanager.h
Normal file
17
libnymea-zigbee/nxp/nxpzigbeenetworkmanager.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef NXPZIGBEENETWORKMANAGER_H
|
||||||
|
#define NXPZIGBEENETWORKMANAGER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class NxpZigbeeNetworkManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit NxpZigbeeNetworkManager(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NXPZIGBEENETWORKMANAGER_H
|
||||||
@ -1,17 +1,15 @@
|
|||||||
#include "zigbeebridgecontroller.h"
|
#include "zigbeebridgecontroller.h"
|
||||||
#include "loggingcategory.h"
|
#include "loggingcategory.h"
|
||||||
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
ZigbeeBridgeController::ZigbeeBridgeController(const QString &serialPort, qint32 baudrate, QObject *parent) :
|
#include <QDataStream>
|
||||||
|
|
||||||
|
ZigbeeBridgeController::ZigbeeBridgeController(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
m_interface = new ZigbeeInterface(this);
|
m_interface = new ZigbeeInterface(this);
|
||||||
|
connect(m_interface, &ZigbeeInterface::availableChanged, this, &ZigbeeBridgeController::availableChanged);
|
||||||
connect(m_interface, &ZigbeeInterface::messageReceived, this, &ZigbeeBridgeController::onMessageReceived);
|
connect(m_interface, &ZigbeeInterface::messageReceived, this, &ZigbeeBridgeController::onMessageReceived);
|
||||||
|
|
||||||
if (!m_interface->enable(serialPort, baudrate)) {
|
|
||||||
qCCritical(dcZigbeeController()) << "Could not enable ZigbeeInterface on" << serialPort;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZigbeeBridgeController::available() const
|
bool ZigbeeBridgeController::available() const
|
||||||
@ -19,6 +17,290 @@ bool ZigbeeBridgeController::available() const
|
|||||||
return m_interface->available();
|
return m_interface->available();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandResetController()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeReset, QByteArray()));
|
||||||
|
request.setDescription("Reset controller");
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandErasePersistantData()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeErasePersistentData, QByteArray()));
|
||||||
|
request.setDescription("Erase persistent data");
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandGetVersion()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeGetVersion, QByteArray()));
|
||||||
|
request.setDescription("Get version");
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeVersionList);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandSetExtendedPanId(quint64 extendedPanId)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << extendedPanId;
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSetExtendetPanId, data));
|
||||||
|
request.setDescription("Set extended PAN id " + QString::number(extendedPanId) + " " + ZigbeeUtils::convertUint64ToHexString(extendedPanId));
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandSetChannelMask(quint32 channelMask)
|
||||||
|
{
|
||||||
|
// Note: 10 < value < 27 -> using sinle channel value
|
||||||
|
// 0x07fff800 select from all channels 11 - 26
|
||||||
|
// 0x2108800 primary zigbee light link channels 11, 15, 20, 25
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << channelMask;
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSetChannelMask, data));
|
||||||
|
request.setDescription("Set channel mask " + ZigbeeUtils::convertByteArrayToHexString(data));
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandSetNodeType(ZigbeeNode::NodeType nodeType)
|
||||||
|
{
|
||||||
|
quint8 deviceTypeValue = 0;
|
||||||
|
if (nodeType == ZigbeeNode::NodeTypeEndDevice) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Set the controller as EndDevice is not allowed. Default to coordinator node type.";
|
||||||
|
deviceTypeValue = static_cast<quint8>(ZigbeeNode::NodeTypeCoordinator);
|
||||||
|
} else {
|
||||||
|
deviceTypeValue = static_cast<quint8>(nodeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << deviceTypeValue;
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSetDeviceType, data));
|
||||||
|
|
||||||
|
switch (nodeType) {
|
||||||
|
case ZigbeeNode::NodeTypeCoordinator:
|
||||||
|
request.setDescription("Set device type coordinator");
|
||||||
|
break;
|
||||||
|
case ZigbeeNode::NodeTypeRouter:
|
||||||
|
request.setDescription("Set device type router");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandStartNetwork()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeStartNetwork, QByteArray()));
|
||||||
|
request.setDescription("Start network");
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNetworkJoinedFormed);
|
||||||
|
request.setTimoutIntervall(12000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandStartScan()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeStartScan, QByteArray()));
|
||||||
|
request.setDescription("Start scan");
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNetworkJoinedFormed);
|
||||||
|
request.setTimoutIntervall(12000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandPermitJoin(quint16 targetAddress, const quint8 advertisingIntervall, bool tcSignificance)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << targetAddress;
|
||||||
|
stream << advertisingIntervall;
|
||||||
|
stream << static_cast<quint8>(tcSignificance);
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypePermitJoiningRequest, data));
|
||||||
|
request.setDescription("Permit joining request on " + ZigbeeUtils::convertUint16ToHexString(targetAddress) + " for " + QString::number(advertisingIntervall) + "[s]");
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandGetPermitJoinStatus()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeGetPermitJoining, QByteArray()));
|
||||||
|
request.setDescription("Get permit joining status");
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeGetPermitJoiningResponse);
|
||||||
|
request.setTimoutIntervall(1000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandRequestLinkQuality(quint16 shortAddress)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << shortAddress;
|
||||||
|
stream << static_cast<quint8>(0);
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeManagementLqiRequest, data));
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeManagementLqiResponse);
|
||||||
|
request.setDescription("Request link quality request for " + ZigbeeUtils::convertUint16ToHexString(shortAddress));
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandEnableWhiteList()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeNetworkWhitelistEnable, QByteArray()));
|
||||||
|
request.setDescription("Enable whitelist");
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandInitiateTouchLink()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeInitiateTouchlink, QByteArray()));
|
||||||
|
request.setDescription("Initiate touch link");
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandTouchLinkFactoryReset()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeTouchlinkFactoryReset, QByteArray()));
|
||||||
|
request.setDescription("Touch link factory reset");
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandNetworkAddressRequest(quint16 targetAddress, quint64 extendedAddress)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << targetAddress;
|
||||||
|
stream << extendedAddress;
|
||||||
|
stream << static_cast<quint8>(1);
|
||||||
|
stream << static_cast<quint8>(0);
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeNetworkAdressRequest, data));
|
||||||
|
request.setDescription("Network address request on " + ZigbeeUtils::convertUint16ToHexString(targetAddress));
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNetworkAdressResponse);
|
||||||
|
request.setTimoutIntervall(1000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandSetSecurityStateAndKey(quint8 keyState, quint8 keySequence, quint8 keyType, const QString &key)
|
||||||
|
{
|
||||||
|
// Note: calls ZPS_vAplSecSetInitialSecurityState
|
||||||
|
|
||||||
|
// Key state:
|
||||||
|
// ZPS_ZDO_PRECONFIGURED_LINK_KEY = 3
|
||||||
|
// This key will be used to encrypt the network key. This is the master or manufacturer key
|
||||||
|
|
||||||
|
// ZPS_ZDO_ZLL_LINK_KEY = 4
|
||||||
|
// This key will be generated by the trust center.
|
||||||
|
|
||||||
|
// Key Type:
|
||||||
|
// ZPS_APS_UNIQUE_LINK_KEY =
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << keyState;
|
||||||
|
stream << keySequence;
|
||||||
|
stream << keyType;
|
||||||
|
stream << QByteArray::fromHex(key.toUtf8());
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSetSecurity, data));
|
||||||
|
request.setDescription("Set security configuration");
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandAuthenticateDevice(const ZigbeeAddress &ieeeAddress, const QString &key)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << ieeeAddress.toUInt64();
|
||||||
|
stream << QByteArray::fromHex(key.toUtf8());
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeAuthenticateDeviceRequest, data));
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeAuthenticateDeviceResponse);
|
||||||
|
request.setDescription(QString("Authenticate device %1").arg(ieeeAddress.toString()));
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandNodeDescriptorRequest(quint16 shortAddress)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << shortAddress;
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeNodeDescriptorRequest, data));
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNodeDescriptorRsponse);
|
||||||
|
request.setDescription("Node descriptor request for " + ZigbeeUtils::convertUint16ToHexString(shortAddress));
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandSimpleDescriptorRequest(quint16 shortAddress, quint8 endpoint)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << shortAddress;
|
||||||
|
stream << endpoint;
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSimpleDescriptorRequest, data));
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeSimpleDescriptorResponse);
|
||||||
|
request.setDescription("Simple node descriptor request for " + ZigbeeUtils::convertUint16ToHexString(shortAddress) + "endpoint " + QString::number(endpoint));
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandPowerDescriptorRequest(quint16 shortAddress)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << shortAddress;
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypePowerDescriptorRequest, data));
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypePowerDescriptorResponse);
|
||||||
|
request.setDescription("Node power descriptor request for " + ZigbeeUtils::convertUint16ToHexString(shortAddress));
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *ZigbeeBridgeController::commandUserDescriptorRequest(quint16 shortAddress, quint16 address)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream << shortAddress;
|
||||||
|
stream << address;
|
||||||
|
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeUserDescriptorRequest, data));
|
||||||
|
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeUserDescriptorResponse);
|
||||||
|
request.setDescription("Node user descriptor request for " + ZigbeeUtils::convertUint16ToHexString(shortAddress) + " " + ZigbeeUtils::convertUint16ToHexString(address));
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
|
|
||||||
|
return sendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeBridgeController::sendMessage(ZigbeeInterfaceReply *reply)
|
void ZigbeeBridgeController::sendMessage(ZigbeeInterfaceReply *reply)
|
||||||
{
|
{
|
||||||
if (!reply)
|
if (!reply)
|
||||||
@ -72,6 +354,16 @@ void ZigbeeBridgeController::onReplyTimeout()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZigbeeBridgeController::enable(const QString &serialPort, qint32 baudrate)
|
||||||
|
{
|
||||||
|
return m_interface->enable(serialPort, baudrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeBridgeController::disable()
|
||||||
|
{
|
||||||
|
m_interface->disable();
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeInterfaceReply *ZigbeeBridgeController::sendRequest(const ZigbeeInterfaceRequest &request)
|
ZigbeeInterfaceReply *ZigbeeBridgeController::sendRequest(const ZigbeeInterfaceRequest &request)
|
||||||
{
|
{
|
||||||
// Create Reply
|
// Create Reply
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
|
||||||
#include "zigbee.h"
|
#include "zigbee.h"
|
||||||
|
#include "zigbeenode.h"
|
||||||
#include "interface/zigbeeinterface.h"
|
#include "interface/zigbeeinterface.h"
|
||||||
#include "interface/zigbeeinterfacereply.h"
|
#include "interface/zigbeeinterfacereply.h"
|
||||||
#include "interface/zigbeeinterfacerequest.h"
|
#include "interface/zigbeeinterfacerequest.h"
|
||||||
@ -14,10 +15,33 @@ class ZigbeeBridgeController : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ZigbeeBridgeController(const QString &serialPort, qint32 baudrate, QObject *parent = nullptr);
|
explicit ZigbeeBridgeController(QObject *parent = nullptr);
|
||||||
|
|
||||||
bool available() const;
|
bool available() const;
|
||||||
|
|
||||||
|
// Direct commands
|
||||||
|
ZigbeeInterfaceReply *commandResetController();
|
||||||
|
ZigbeeInterfaceReply *commandErasePersistantData();
|
||||||
|
ZigbeeInterfaceReply *commandGetVersion();
|
||||||
|
ZigbeeInterfaceReply *commandSetExtendedPanId(quint64 extendedPanId);
|
||||||
|
ZigbeeInterfaceReply *commandSetChannelMask(quint32 channelMask = 0x07fff800);
|
||||||
|
ZigbeeInterfaceReply *commandSetNodeType(ZigbeeNode::NodeType nodeType);
|
||||||
|
ZigbeeInterfaceReply *commandStartNetwork();
|
||||||
|
ZigbeeInterfaceReply *commandStartScan();
|
||||||
|
ZigbeeInterfaceReply *commandPermitJoin(quint16 targetAddress = 0xfffc, const quint8 advertisingIntervall = 180, bool tcSignificance = false);
|
||||||
|
ZigbeeInterfaceReply *commandGetPermitJoinStatus();
|
||||||
|
ZigbeeInterfaceReply *commandRequestLinkQuality(quint16 shortAddress);
|
||||||
|
ZigbeeInterfaceReply *commandEnableWhiteList();
|
||||||
|
ZigbeeInterfaceReply *commandInitiateTouchLink();
|
||||||
|
ZigbeeInterfaceReply *commandTouchLinkFactoryReset();
|
||||||
|
ZigbeeInterfaceReply *commandNetworkAddressRequest(quint16 targetAddress, quint64 extendedAddress);
|
||||||
|
ZigbeeInterfaceReply *commandSetSecurityStateAndKey(quint8 keyState, quint8 keySequence, quint8 keyType, const QString &key);
|
||||||
|
ZigbeeInterfaceReply *commandAuthenticateDevice(const ZigbeeAddress &ieeeAddress, const QString &key);
|
||||||
|
ZigbeeInterfaceReply *commandNodeDescriptorRequest(quint16 shortAddress);
|
||||||
|
ZigbeeInterfaceReply *commandSimpleDescriptorRequest(quint16 shortAddress, quint8 endpoint);
|
||||||
|
ZigbeeInterfaceReply *commandPowerDescriptorRequest(quint16 shortAddress);
|
||||||
|
ZigbeeInterfaceReply *commandUserDescriptorRequest(quint16 shortAddress, quint16 address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeInterface *m_interface = nullptr;
|
ZigbeeInterface *m_interface = nullptr;
|
||||||
ZigbeeInterfaceReply *m_currentReply = nullptr;
|
ZigbeeInterfaceReply *m_currentReply = nullptr;
|
||||||
@ -27,6 +51,7 @@ private:
|
|||||||
void sendMessage(ZigbeeInterfaceReply *reply);
|
void sendMessage(ZigbeeInterfaceReply *reply);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void availableChanged(bool available);
|
||||||
void messageReceived(const ZigbeeInterfaceMessage &message);
|
void messageReceived(const ZigbeeInterfaceMessage &message);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@ -34,8 +59,10 @@ private slots:
|
|||||||
void onReplyTimeout();
|
void onReplyTimeout();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ZigbeeInterfaceReply *sendRequest(const ZigbeeInterfaceRequest &request);
|
bool enable(const QString &serialPort, qint32 baudrate);
|
||||||
|
void disable();
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *sendRequest(const ZigbeeInterfaceRequest &request);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
143
libnymea-zigbee/zigbeenetwork.cpp
Normal file
143
libnymea-zigbee/zigbeenetwork.cpp
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#include "zigbeenetwork.h"
|
||||||
|
#include "loggingcategory.h"
|
||||||
|
|
||||||
|
ZigbeeNetwork::ZigbeeNetwork(ControllerType controllerType, QObject *parent) :
|
||||||
|
ZigbeeNode(parent),
|
||||||
|
m_controllerType(controllerType)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNetwork::State ZigbeeNetwork::state() const
|
||||||
|
{
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNetwork::ControllerType ZigbeeNetwork::controlerType() const
|
||||||
|
{
|
||||||
|
return m_controllerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNetwork::Error ZigbeeNetwork::error() const
|
||||||
|
{
|
||||||
|
return m_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ZigbeeNetwork::serialPortName() const
|
||||||
|
{
|
||||||
|
return m_serialPortName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setSerialPortName(const QString &serialPortName)
|
||||||
|
{
|
||||||
|
m_serialPortName = serialPortName;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32 ZigbeeNetwork::serialBaudrate() const
|
||||||
|
{
|
||||||
|
return m_serialBaudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setSerialBaudrate(qint32 baudrate)
|
||||||
|
{
|
||||||
|
m_serialBaudrate = baudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 ZigbeeNetwork::extendedPanId() const
|
||||||
|
{
|
||||||
|
return m_extendedPanId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setExtendedPanId(quint64 extendedPanId)
|
||||||
|
{
|
||||||
|
m_extendedPanId = extendedPanId;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint ZigbeeNetwork::channel() const
|
||||||
|
{
|
||||||
|
return m_channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setChannel(uint channel)
|
||||||
|
{
|
||||||
|
m_channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeSecurityConfiguration ZigbeeNetwork::securityConfiguration() const
|
||||||
|
{
|
||||||
|
return m_securityConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration)
|
||||||
|
{
|
||||||
|
m_securityConfiguration = securityConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ZigbeeNode *> ZigbeeNetwork::nodes() const
|
||||||
|
{
|
||||||
|
return m_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNode *ZigbeeNetwork::getZigbeeNode(quint16 shortAddress)
|
||||||
|
{
|
||||||
|
foreach (ZigbeeNode *node, m_nodes) {
|
||||||
|
if (node->shortAddress() == shortAddress) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNode *ZigbeeNetwork::getZigbeeNode(ZigbeeAddress address)
|
||||||
|
{
|
||||||
|
foreach (ZigbeeNode *node, m_nodes) {
|
||||||
|
if (node->extendedAddress() == address) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::addNode(ZigbeeNode *node)
|
||||||
|
{
|
||||||
|
if (m_nodes.contains(node)) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "The node" << node << "has already been added.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nodes.append(node);
|
||||||
|
emit nodeAdded(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::removeNode(ZigbeeNode *node)
|
||||||
|
{
|
||||||
|
if (!m_nodes.contains(node)) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "Try to remove node" << node << "but not in the node list.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nodes.removeAll(node);
|
||||||
|
emit nodeRemoved(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setState(ZigbeeNetwork::State state)
|
||||||
|
{
|
||||||
|
if (m_state == state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "State changed" << state;
|
||||||
|
m_state = state;
|
||||||
|
emit stateChanged(m_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setError(ZigbeeNetwork::Error error)
|
||||||
|
{
|
||||||
|
if (m_error == error)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_error != ErrorNoError) qCDebug(dcZigbeeNetwork()) << "Error occured" << error;
|
||||||
|
m_error = error;
|
||||||
|
emit errorOccured(m_error);
|
||||||
|
}
|
||||||
99
libnymea-zigbee/zigbeenetwork.h
Normal file
99
libnymea-zigbee/zigbeenetwork.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#ifndef ZIGBEENETWORK_H
|
||||||
|
#define ZIGBEENETWORK_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "zigbeenode.h"
|
||||||
|
#include "zigbeesecurityconfiguration.h"
|
||||||
|
|
||||||
|
class ZigbeeNetwork : public ZigbeeNode
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ControllerType {
|
||||||
|
ControlerTypeNxp
|
||||||
|
};
|
||||||
|
Q_ENUM(ControllerType)
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
StateDisconnected,
|
||||||
|
StateStarting,
|
||||||
|
StateRunning,
|
||||||
|
StateStopping
|
||||||
|
};
|
||||||
|
Q_ENUM(State)
|
||||||
|
|
||||||
|
enum Error {
|
||||||
|
ErrorNoError,
|
||||||
|
ErrorHardwareUnavailable
|
||||||
|
};
|
||||||
|
Q_ENUM(Error)
|
||||||
|
|
||||||
|
explicit ZigbeeNetwork(ControllerType controllerType, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
State state() const;
|
||||||
|
ControllerType controlerType() const;
|
||||||
|
|
||||||
|
Error error() const;
|
||||||
|
|
||||||
|
// Serial port configuration
|
||||||
|
QString serialPortName() const;
|
||||||
|
void setSerialPortName(const QString &serialPortName);
|
||||||
|
|
||||||
|
qint32 serialBaudrate() const;
|
||||||
|
void setSerialBaudrate(qint32 baudrate);
|
||||||
|
|
||||||
|
// Network configurations
|
||||||
|
quint64 extendedPanId() const;
|
||||||
|
void setExtendedPanId(quint64 extendedPanId);
|
||||||
|
|
||||||
|
uint channel() const;
|
||||||
|
void setChannel(uint channel);
|
||||||
|
|
||||||
|
ZigbeeSecurityConfiguration securityConfiguration() const;
|
||||||
|
void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration);
|
||||||
|
|
||||||
|
QList<ZigbeeNode *> nodes() const;
|
||||||
|
|
||||||
|
ZigbeeNode *getZigbeeNode(quint16 shortAddress);
|
||||||
|
ZigbeeNode *getZigbeeNode(ZigbeeAddress address);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ControllerType m_controllerType = ControlerTypeNxp;
|
||||||
|
State m_state = StateDisconnected;
|
||||||
|
Error m_error = ErrorNoError;
|
||||||
|
|
||||||
|
// Serial port configuration
|
||||||
|
QString m_serialPortName = "/dev/ttyUSB0";
|
||||||
|
qint32 m_serialBaudrate = 115200;
|
||||||
|
|
||||||
|
// Network configurations
|
||||||
|
quint64 m_extendedPanId = 0;
|
||||||
|
uint m_channel = 0;
|
||||||
|
ZigbeeSecurityConfiguration m_securityConfiguration;
|
||||||
|
ZigbeeNode::NodeType m_nodeType = ZigbeeNode::NodeTypeCoordinator;
|
||||||
|
|
||||||
|
QList<ZigbeeNode *> m_nodes;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void addNode(ZigbeeNode *node);
|
||||||
|
void removeNode(ZigbeeNode *node);
|
||||||
|
|
||||||
|
void setState(State state);
|
||||||
|
void setError(Error error);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void nodeAdded(ZigbeeNode *node);
|
||||||
|
void nodeRemoved(ZigbeeNode *node);
|
||||||
|
|
||||||
|
void stateChanged(State state);
|
||||||
|
void errorOccured(Error error);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void startNetwork() = 0;
|
||||||
|
virtual void stopNetwork() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ZIGBEENETWORK_H
|
||||||
File diff suppressed because it is too large
Load Diff
@ -3,100 +3,77 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "zigbeenode.h"
|
#include "zigbeenetwork.h"
|
||||||
#include "zigbeeaddress.h"
|
#include "zigbeeaddress.h"
|
||||||
#include "zigbeebridgecontroller.h"
|
#include "zigbeebridgecontroller.h"
|
||||||
|
#include "zigbeesecurityconfiguration.h"
|
||||||
|
|
||||||
class ZigbeeNetworkManager : public ZigbeeNode
|
class ZigbeeNetworkManager : public ZigbeeNetwork
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ZigbeeNetworkManager(const int &channel = 0, const QString &serialPort = "/dev/ttyS0", qint32 baudrate = 115200, QObject *parent = nullptr);
|
explicit ZigbeeNetworkManager(QObject *parent = nullptr);
|
||||||
|
|
||||||
bool isAvailable() const;
|
|
||||||
|
|
||||||
QString controllerVersion() const;
|
QString controllerVersion() const;
|
||||||
QString serialPort() const;
|
|
||||||
QList<ZigbeeNode *> nodeList() const;
|
|
||||||
quint64 extendedPanId() const;
|
|
||||||
|
|
||||||
bool networkRunning() const;
|
bool networkRunning() const;
|
||||||
|
|
||||||
// Controller methods
|
|
||||||
void resetController();
|
|
||||||
void erasePersistentData();
|
|
||||||
void sendDataManagerAvailableResponse();
|
|
||||||
void getVersion();
|
|
||||||
void setExtendedPanId(const quint64 &panId);
|
|
||||||
void setChannelMask(const quint32 &channelMask = 0x07fff800);
|
|
||||||
void setDeviceType(const NodeType &deviceType);
|
|
||||||
void startNetwork();
|
|
||||||
void startScan();
|
|
||||||
|
|
||||||
void permitJoining(quint16 targetAddress = 0xfffc, const quint8 advertisingIntervall = 180, bool tcSignificance = false);
|
|
||||||
|
|
||||||
void requestLinkQuality();
|
|
||||||
|
|
||||||
void getPermitJoiningStatus();
|
|
||||||
void enableWhitelist();
|
|
||||||
|
|
||||||
void initiateTouchLink();
|
|
||||||
void touchLinkFactoryReset();
|
|
||||||
|
|
||||||
void networkAddressRequest(quint16 targetAddress, quint64 extendedAddress);
|
|
||||||
|
|
||||||
void requestMatchDescriptor(const quint16 &shortAddress, const Zigbee::ZigbeeProfile &profile);
|
|
||||||
|
|
||||||
void setInitialSecurity(quint8 keyState, quint8 keySequence, quint8 keyType, const QString &key);
|
|
||||||
|
|
||||||
void authenticateDevice(const ZigbeeAddress &ieeeAddress);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum StartingState {
|
||||||
|
StartingStateNone,
|
||||||
|
StartingStateErase,
|
||||||
|
StartingStateReset,
|
||||||
|
StartingStateGetVersion,
|
||||||
|
StartingStateSetPanId,
|
||||||
|
StartingStateSetChannel,
|
||||||
|
StartingStateSetSecurity,
|
||||||
|
StartingStateStartNetwork,
|
||||||
|
StartingStateReadeNodeDescriptor,
|
||||||
|
StartingStateReadSimpleDescriptor,
|
||||||
|
StartingStateReadPowerDescriptor
|
||||||
|
};
|
||||||
|
|
||||||
ZigbeeBridgeController *m_controller = nullptr;
|
ZigbeeBridgeController *m_controller = nullptr;
|
||||||
QString m_serialPort;
|
|
||||||
QString m_controllerVersion;
|
QString m_controllerVersion;
|
||||||
quint64 m_extendedPanId = 0;
|
|
||||||
|
|
||||||
QList<ZigbeeNode *> m_nodeList;
|
StartingState m_startingState = StartingStateNone;
|
||||||
|
void setStartingState(StartingState state);
|
||||||
bool m_networkRunning = false;
|
|
||||||
|
|
||||||
quint64 generateRandomPanId();
|
|
||||||
|
|
||||||
void parseNetworkFormed(const QByteArray &data);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void runningChanged(const bool &running);
|
void runningChanged(const bool &running);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onMessageReceived(const ZigbeeInterfaceMessage &message);
|
void onMessageReceived(const ZigbeeInterfaceMessage &message);
|
||||||
|
void onControllerAvailableChanged(bool available);
|
||||||
|
|
||||||
void loadNetwork();
|
// Controller command finished slots
|
||||||
void saveNetwork();
|
void onCommandResetControllerFinished();
|
||||||
|
void onCommandErasePersistentDataFinished();
|
||||||
|
void onCommandGetVersionFinished();
|
||||||
|
void onCommandSetExtendedPanIdFinished();
|
||||||
|
void onCommandSetChannelMaskFinished();
|
||||||
|
void onCommandSetDeviceTypeFinished();
|
||||||
|
void onCommandStartNetworkFinished();
|
||||||
|
void onCommandStartScanFinished();
|
||||||
|
void onCommandGetPermitJoiningStatusFinished();
|
||||||
|
void onCommandPermitJoiningFinished();
|
||||||
|
void onCommandEnableWhitelistFinished();
|
||||||
|
|
||||||
// Controller methods finished slots
|
void onCommandNodeDescriptorRequestFinished();
|
||||||
void onResetControllerFinished();
|
void onCommandSimpleDescriptorRequestFinished();
|
||||||
void onErasePersistentDataFinished();
|
void onCommandPowerDescriptorRequestFinished();
|
||||||
void onGetVersionFinished();
|
|
||||||
void onSetExtendedPanIdFinished();
|
|
||||||
void onSetChannelMaskFinished();
|
|
||||||
void onSetDeviceTypeFinished();
|
|
||||||
void onStartNetworkFinished();
|
|
||||||
void onStartScanFinished();
|
|
||||||
void onGetPermitJoiningStatusFinished();
|
|
||||||
void onPermitJoiningFinished();
|
|
||||||
void onEnableWhitelistFinished();
|
|
||||||
|
|
||||||
void onInitiateTouchLinkFinished();
|
void onCommandInitiateTouchLinkFinished();
|
||||||
void onTouchLinkFactoryResetFinished();
|
void onCommandTouchLinkFactoryResetFinished();
|
||||||
void onRequestLinkQualityFinished();
|
void onCommandRequestLinkQualityFinished();
|
||||||
|
|
||||||
void onRequestMatchDescriptorFinished();
|
void onCommandRequestMatchDescriptorFinished();
|
||||||
void onSetSecurityFinished();
|
void onCommandSetSecurityFinished();
|
||||||
void onNetworkAddressRequestFinished();
|
void onCommandNetworkAddressRequestFinished();
|
||||||
void onAuthenticateDeviceFinished();
|
void onCommandAuthenticateDeviceFinished();
|
||||||
|
|
||||||
// Process controller notifications/messages
|
// Process controller notifications/messages
|
||||||
|
void processNetworkFormed(const ZigbeeInterfaceMessage &message);
|
||||||
void processLoggingMessage(const ZigbeeInterfaceMessage &message);
|
void processLoggingMessage(const ZigbeeInterfaceMessage &message);
|
||||||
void processFactoryNewRestart(const ZigbeeInterfaceMessage &message);
|
void processFactoryNewRestart(const ZigbeeInterfaceMessage &message);
|
||||||
void processNodeClusterList(const ZigbeeInterfaceMessage &message);
|
void processNodeClusterList(const ZigbeeInterfaceMessage &message);
|
||||||
@ -106,6 +83,11 @@ private slots:
|
|||||||
void processAttributeReport(const ZigbeeInterfaceMessage &message);
|
void processAttributeReport(const ZigbeeInterfaceMessage &message);
|
||||||
void processLeaveIndication(const ZigbeeInterfaceMessage &message);
|
void processLeaveIndication(const ZigbeeInterfaceMessage &message);
|
||||||
void processRestartProvisioned(const ZigbeeInterfaceMessage &message);
|
void processRestartProvisioned(const ZigbeeInterfaceMessage &message);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void startNetwork() override;
|
||||||
|
void stopNetwork() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ZIGBEEMANAGER_H
|
#endif // ZIGBEEMANAGER_H
|
||||||
|
|||||||
@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
|
||||||
|
ZigbeeNode::ZigbeeNode(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
quint16 ZigbeeNode::shortAddress() const
|
quint16 ZigbeeNode::shortAddress() const
|
||||||
{
|
{
|
||||||
return m_shortAddress;
|
return m_shortAddress;
|
||||||
@ -14,7 +20,7 @@ ZigbeeAddress ZigbeeNode::extendedAddress() const
|
|||||||
return m_extendedAddress;
|
return m_extendedAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZigbeeNode::endPoint() const
|
quint8 ZigbeeNode::endPoint() const
|
||||||
{
|
{
|
||||||
return m_endPoint;
|
return m_endPoint;
|
||||||
}
|
}
|
||||||
@ -29,9 +35,9 @@ ZigbeeNode::FrequencyBand ZigbeeNode::frequencyBand() const
|
|||||||
return m_frequencyBand;
|
return m_frequencyBand;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeNode::Relationship ZigbeeNode::relationShip() const
|
ZigbeeNode::Relationship ZigbeeNode::relationship() const
|
||||||
{
|
{
|
||||||
return m_relationShip;
|
return m_relationship;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zigbee::ZigbeeProfile ZigbeeNode::profile() const
|
Zigbee::ZigbeeProfile ZigbeeNode::profile() const
|
||||||
@ -44,6 +50,31 @@ quint16 ZigbeeNode::manufacturerCode() const
|
|||||||
return m_manufacturerCode;
|
return m_manufacturerCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZigbeeNode::complexDescriptorAvailable() const
|
||||||
|
{
|
||||||
|
return m_complexDescriptorAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigbeeNode::userDescriptorAvailable() const
|
||||||
|
{
|
||||||
|
return m_userDescriptorAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 ZigbeeNode::maximumRxSize() const
|
||||||
|
{
|
||||||
|
return m_maximumRxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 ZigbeeNode::maximumTxSize() const
|
||||||
|
{
|
||||||
|
return m_maximumTxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 ZigbeeNode::maximumBufferSize() const
|
||||||
|
{
|
||||||
|
return m_maximumBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeNode::PowerMode ZigbeeNode::powerMode() const
|
ZigbeeNode::PowerMode ZigbeeNode::powerMode() const
|
||||||
{
|
{
|
||||||
return m_powerMode;
|
return m_powerMode;
|
||||||
@ -64,16 +95,9 @@ ZigbeeNode::PowerLevel ZigbeeNode::powerLevel() const
|
|||||||
return m_powerLevel;
|
return m_powerLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNode::init()
|
|
||||||
{
|
|
||||||
requestNodeDescription();
|
|
||||||
requestSimpleNodeDescription();
|
|
||||||
requestPowerDescriptor();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//void ZigbeeNode::identify()
|
||||||
void ZigbeeNode::identify()
|
//{
|
||||||
{
|
|
||||||
// QByteArray data;
|
// QByteArray data;
|
||||||
// QDataStream stream(&data, QIODevice::WriteOnly);
|
// QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
// stream << m_shortAddress;
|
// stream << m_shortAddress;
|
||||||
@ -86,98 +110,26 @@ void ZigbeeNode::identify()
|
|||||||
|
|
||||||
// ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
// ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
||||||
// connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onRequestLinkQuality);
|
// connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onRequestLinkQuality);
|
||||||
}
|
//}
|
||||||
|
|
||||||
void ZigbeeNode::toggle(int addressMode)
|
//void ZigbeeNode::toggle(int addressMode)
|
||||||
{
|
//{
|
||||||
QByteArray data;
|
// QByteArray data;
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
// QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
stream << static_cast<quint8>(addressMode); // adress mode
|
// stream << static_cast<quint8>(addressMode); // adress mode
|
||||||
stream << m_shortAddress;
|
// stream << m_shortAddress;
|
||||||
stream << static_cast<quint8>(1); // source endpoint
|
// stream << static_cast<quint8>(1); // source endpoint
|
||||||
stream << static_cast<quint8>(1); // destination endpoint
|
// stream << static_cast<quint8>(1); // destination endpoint
|
||||||
stream << static_cast<quint8>(2); // command toggle
|
// stream << static_cast<quint8>(2); // command toggle
|
||||||
|
|
||||||
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeCluserOnOff, data));
|
// ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeCluserOnOff, data));
|
||||||
request.setDescription("Toggle request for " + ZigbeeUtils::convertUint16ToHexString(m_shortAddress));
|
// request.setDescription("Toggle request for " + ZigbeeUtils::convertUint16ToHexString(m_shortAddress));
|
||||||
|
|
||||||
ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
// ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
||||||
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onToggleFinished);
|
// connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onToggleFinished);
|
||||||
}
|
//}
|
||||||
|
|
||||||
void ZigbeeNode::requestNodeDescription()
|
|
||||||
{
|
|
||||||
QByteArray data;
|
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
|
||||||
stream << m_shortAddress;
|
|
||||||
|
|
||||||
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeNodeDescriptorRequest, data));
|
|
||||||
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNodeDescriptorRsponse);
|
|
||||||
request.setDescription("Node descriptor request for " + ZigbeeUtils::convertUint16ToHexString(m_shortAddress));
|
|
||||||
request.setTimoutIntervall(5000);
|
|
||||||
|
|
||||||
ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
|
||||||
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onRequestNodeDescriptionFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNode::requestSimpleNodeDescription()
|
|
||||||
{
|
|
||||||
QByteArray data;
|
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
|
||||||
stream << m_shortAddress;
|
|
||||||
stream << quint8(1);
|
|
||||||
|
|
||||||
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSimpleDescriptorRequest, data));
|
|
||||||
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeSimpleDescriptorResponse);
|
|
||||||
request.setDescription("Simple node descriptor request for " + ZigbeeUtils::convertUint16ToHexString(m_shortAddress));
|
|
||||||
request.setTimoutIntervall(5000);
|
|
||||||
|
|
||||||
ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
|
||||||
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onRequestSimpleNodeDescriptionFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNode::requestPowerDescriptor()
|
|
||||||
{
|
|
||||||
QByteArray data;
|
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
|
||||||
stream << m_shortAddress;
|
|
||||||
|
|
||||||
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypePowerDescriptorRequest, data));
|
|
||||||
request.setExpectedAdditionalMessageType(Zigbee::MessageTypePowerDescriptorResponse);
|
|
||||||
request.setDescription("Node power descriptor request for " + ZigbeeUtils::convertUint16ToHexString(m_shortAddress));
|
|
||||||
request.setTimoutIntervall(5000);
|
|
||||||
|
|
||||||
ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
|
||||||
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onRequestPowerDescriptorFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNode::requestUserDescriptor()
|
|
||||||
{
|
|
||||||
QByteArray data;
|
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
|
||||||
stream << m_shortAddress;
|
|
||||||
stream << static_cast<quint16>(0);
|
|
||||||
|
|
||||||
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeUserDescriptorRequest, data));
|
|
||||||
request.setExpectedAdditionalMessageType(Zigbee::MessageTypeUserDescriptorResponse);
|
|
||||||
request.setDescription("Node user descriptor request for " + ZigbeeUtils::convertUint16ToHexString(m_shortAddress));
|
|
||||||
request.setTimoutIntervall(5000);
|
|
||||||
|
|
||||||
ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
|
||||||
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onRequestUserDescriptorFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZigbeeNode::ZigbeeNode(ZigbeeBridgeController *controller, QObject *parent) :
|
|
||||||
QObject(parent),
|
|
||||||
m_controller(controller)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ZigbeeBridgeController *ZigbeeNode::controller()
|
|
||||||
{
|
|
||||||
return m_controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNode::setShortAddress(const quint16 &shortAddress)
|
void ZigbeeNode::setShortAddress(const quint16 &shortAddress)
|
||||||
{
|
{
|
||||||
@ -189,55 +141,53 @@ void ZigbeeNode::setExtendedAddress(const ZigbeeAddress &extendedAddress)
|
|||||||
m_extendedAddress = extendedAddress;
|
m_extendedAddress = extendedAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNode::onRequestNodeDescriptionFinished()
|
void ZigbeeNode::setEndPoint(quint8 endPoint)
|
||||||
{
|
{
|
||||||
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
m_endPoint = endPoint;
|
||||||
reply->deleteLater();
|
}
|
||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
void ZigbeeNode::setNodeType(ZigbeeNode::NodeType nodeType)
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
{
|
||||||
return;
|
m_nodeType = nodeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
void ZigbeeNode::setFrequencyBand(ZigbeeNode::FrequencyBand frequencyBand)
|
||||||
|
{
|
||||||
|
m_frequencyBand = frequencyBand;
|
||||||
|
}
|
||||||
|
|
||||||
quint8 sequenceNumber = static_cast<quint8>(reply->additionalMessage().data().at(0));
|
void ZigbeeNode::setRelationship(ZigbeeNode::Relationship relationship)
|
||||||
quint8 status = static_cast<quint8>(reply->additionalMessage().data().at(1));
|
{
|
||||||
|
m_relationship = relationship;
|
||||||
|
}
|
||||||
|
|
||||||
quint16 shortAddress = reply->additionalMessage().data().at(2);
|
void ZigbeeNode::setZigbeeProfile(Zigbee::ZigbeeProfile profile)
|
||||||
shortAddress <<= 8;
|
{
|
||||||
shortAddress |= reply->additionalMessage().data().at(3);
|
m_profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
quint16 manufacturerCode = reply->additionalMessage().data().at(4);
|
void ZigbeeNode::setManufacturerCode(quint16 manufacturerCode)
|
||||||
manufacturerCode <<= 8;
|
{
|
||||||
manufacturerCode |= reply->additionalMessage().data().at(5);
|
|
||||||
|
|
||||||
quint16 maximalRxSize = reply->additionalMessage().data().at(6);
|
|
||||||
maximalRxSize <<= 8;
|
|
||||||
maximalRxSize |= reply->additionalMessage().data().at(7);
|
|
||||||
|
|
||||||
quint16 maximalTxSize = reply->additionalMessage().data().at(8);
|
|
||||||
maximalTxSize <<= 8;
|
|
||||||
maximalTxSize |= reply->additionalMessage().data().at(9);
|
|
||||||
|
|
||||||
quint16 serverMask = reply->additionalMessage().data().at(10);
|
|
||||||
serverMask <<= 8;
|
|
||||||
serverMask |= reply->additionalMessage().data().at(11);
|
|
||||||
|
|
||||||
quint8 descriptorFlag = static_cast<quint8>(reply->additionalMessage().data().at(12));
|
|
||||||
quint8 macFlags = static_cast<quint8>(reply->additionalMessage().data().at(13));
|
|
||||||
quint8 maxBufferSize = static_cast<quint8>(reply->additionalMessage().data().at(14));
|
|
||||||
|
|
||||||
quint16 bitField = reply->additionalMessage().data().at(15);
|
|
||||||
bitField <<= 8;
|
|
||||||
bitField |= reply->additionalMessage().data().at(16);
|
|
||||||
|
|
||||||
// Set node data
|
|
||||||
m_manufacturerCode = manufacturerCode;
|
m_manufacturerCode = manufacturerCode;
|
||||||
m_maximalRxSize = maximalRxSize;
|
}
|
||||||
m_maximalTxSize = maximalTxSize;
|
|
||||||
|
|
||||||
// Parse server mask
|
void ZigbeeNode::setMaximumRxSize(quint16 size)
|
||||||
|
{
|
||||||
|
m_maximumRxSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNode::setMaximumTxSize(quint16 size)
|
||||||
|
{
|
||||||
|
m_maximumTxSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNode::setMaximumBufferSize(quint8 size)
|
||||||
|
{
|
||||||
|
m_maximumBufferSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNode::setServerMask(quint16 serverMask)
|
||||||
|
{
|
||||||
m_isPrimaryTrustCenter = ((serverMask >> 0) & 0x0001);
|
m_isPrimaryTrustCenter = ((serverMask >> 0) & 0x0001);
|
||||||
m_isBackupTrustCenter = ((serverMask >> 1) & 0x0001);
|
m_isBackupTrustCenter = ((serverMask >> 1) & 0x0001);
|
||||||
m_isPrimaryBindingCache = ((serverMask >> 2) & 0x0001);
|
m_isPrimaryBindingCache = ((serverMask >> 2) & 0x0001);
|
||||||
@ -245,298 +195,94 @@ void ZigbeeNode::onRequestNodeDescriptionFinished()
|
|||||||
m_isPrimaryDiscoveryCache = ((serverMask >> 4) & 0x0001);
|
m_isPrimaryDiscoveryCache = ((serverMask >> 4) & 0x0001);
|
||||||
m_isBackupDiscoveryCache = ((serverMask >> 5) & 0x0001);
|
m_isBackupDiscoveryCache = ((serverMask >> 5) & 0x0001);
|
||||||
m_isNetworkManager = ((serverMask >> 6) & 0x0001);
|
m_isNetworkManager = ((serverMask >> 6) & 0x0001);
|
||||||
|
}
|
||||||
|
|
||||||
// Parse desciptor flag
|
void ZigbeeNode::setComplexDescriptorAvailable(bool complexDescriptorAvailable)
|
||||||
bool extendedActiveEndpointListAvailable = ((descriptorFlag >> 0) & 0x01);
|
{
|
||||||
bool extendedSimpleDescriptorListAvailable = ((descriptorFlag >> 1) & 0x01);
|
m_complexDescriptorAvailable = complexDescriptorAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNode::setUserDescriptorAvailable(bool userDescriptorAvailable)
|
||||||
|
{
|
||||||
|
m_userDescriptorAvailable = userDescriptorAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNode::setMacCapabilitiesFlag(quint16 macFlag)
|
||||||
|
{
|
||||||
// Parse MAC capabilities
|
// Parse MAC capabilities
|
||||||
m_receiverOnWhenIdle = ((macFlags >> 3) & 0x01);
|
m_alternatePanCoordinator = ((macFlag >> 0) & 0x01);
|
||||||
m_securityCapability = ((macFlags >> 6) & 0x01);
|
if (((macFlag >> 1) & 0x01)) {
|
||||||
|
m_deviceType = DeviceTypeFullFunction;
|
||||||
// Parse bit field
|
|
||||||
bool isCoordinator = ((bitField >> 0) & 0x0001);
|
|
||||||
bool isRouter = ((bitField >> 1) & 0x0001);
|
|
||||||
bool isEndDevice = ((bitField >> 2) & 0x0001);
|
|
||||||
bool complexDescriptorAvailable = ((bitField >> 3) & 0x0001);
|
|
||||||
bool userDescriptorAvailable = ((bitField >> 4) & 0x0001);
|
|
||||||
|
|
||||||
if (isCoordinator && !isRouter && !isEndDevice) {
|
|
||||||
m_nodeType = NodeTypeCoordinator;
|
|
||||||
} else if (!isCoordinator && isRouter && !isEndDevice) {
|
|
||||||
m_nodeType = NodeTypeRouter;
|
|
||||||
} else if (!isCoordinator && !isRouter && isEndDevice) {
|
|
||||||
m_nodeType = NodeTypeEndDevice;
|
|
||||||
} else {
|
} else {
|
||||||
if (m_isNetworkManager) {
|
m_deviceType = DeviceTypeReducedFunction;
|
||||||
m_nodeType = NodeTypeCoordinator;
|
|
||||||
} else {
|
|
||||||
m_nodeType = NodeTypeEndDevice;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
m_powerSourceFlagMainPower = ((macFlag >> 2) & 0x01);
|
||||||
// Note: Frequency always 2,4 GHz
|
m_receiverOnWhenIdle = ((macFlag >> 3) & 0x01);
|
||||||
|
m_securityCapability = ((macFlag >> 6) & 0x01);
|
||||||
qCDebug(dcZigbee()) << "Node descriptor:";
|
m_allocateAddress = ((macFlag >> 7) & 0x01);
|
||||||
qCDebug(dcZigbee()) << " Node type:" << m_nodeType;
|
|
||||||
qCDebug(dcZigbee()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber);
|
|
||||||
qCDebug(dcZigbee()) << " Status:" << ZigbeeUtils::convertByteToHexString(status);
|
|
||||||
qCDebug(dcZigbee()) << " Short address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress);
|
|
||||||
qCDebug(dcZigbee()) << " Manufacturer code:" << ZigbeeUtils::convertUint16ToHexString(manufacturerCode);
|
|
||||||
qCDebug(dcZigbee()) << " Maximum Rx size:" << ZigbeeUtils::convertUint16ToHexString(m_maximalRxSize);
|
|
||||||
qCDebug(dcZigbee()) << " Maximum Tx size:" << ZigbeeUtils::convertUint16ToHexString(m_maximalTxSize);
|
|
||||||
qCDebug(dcZigbee()) << " Server mask:" << ZigbeeUtils::convertUint16ToHexString(serverMask);
|
|
||||||
qCDebug(dcZigbee()) << " Primary Trust center:" << m_isPrimaryTrustCenter;
|
|
||||||
qCDebug(dcZigbee()) << " Backup Trust center:" << m_isBackupTrustCenter;
|
|
||||||
qCDebug(dcZigbee()) << " Primary Binding cache:" << m_isPrimaryBindingCache;
|
|
||||||
qCDebug(dcZigbee()) << " Backup Binding cache:" << m_isBackupBindingCache;
|
|
||||||
qCDebug(dcZigbee()) << " Primary Discovery cache:" << m_isPrimaryDiscoveryCache;
|
|
||||||
qCDebug(dcZigbee()) << " Backup Discovery cache:" << m_isBackupDiscoveryCache;
|
|
||||||
qCDebug(dcZigbee()) << " Network Manager:" << m_isNetworkManager;
|
|
||||||
qCDebug(dcZigbee()) << " Descriptor flag:" << ZigbeeUtils::convertByteToHexString(descriptorFlag);
|
|
||||||
qCDebug(dcZigbee()) << " Extended active endpoint list available:" << extendedActiveEndpointListAvailable;
|
|
||||||
qCDebug(dcZigbee()) << " Extended simple descriptor list available:" << extendedSimpleDescriptorListAvailable;
|
|
||||||
qCDebug(dcZigbee()) << " MAC flags:" << ZigbeeUtils::convertByteToHexString(macFlags);
|
|
||||||
qCDebug(dcZigbee()) << " Receiver on when idle:" << m_receiverOnWhenIdle;
|
|
||||||
qCDebug(dcZigbee()) << " Security capability:" << m_securityCapability;
|
|
||||||
qCDebug(dcZigbee()) << " Maximum buffer size:" << ZigbeeUtils::convertByteToHexString(maxBufferSize);
|
|
||||||
qCDebug(dcZigbee()) << " Bit field:" << ZigbeeUtils::convertUint16ToHexString(bitField);
|
|
||||||
qCDebug(dcZigbee()) << " Is coordinator:" << isCoordinator;
|
|
||||||
qCDebug(dcZigbee()) << " Is router:" << isRouter;
|
|
||||||
qCDebug(dcZigbee()) << " Is end device:" << isEndDevice;
|
|
||||||
qCDebug(dcZigbee()) << " Complex desciptor available:" << complexDescriptorAvailable;
|
|
||||||
qCDebug(dcZigbee()) << " User desciptor available:" << userDescriptorAvailable;
|
|
||||||
|
|
||||||
|
|
||||||
if (userDescriptorAvailable) {
|
|
||||||
requestUserDescriptor();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNode::onRequestSimpleNodeDescriptionFinished()
|
void ZigbeeNode::setDescriptorFlag(quint8 descriptorFlag)
|
||||||
{
|
{
|
||||||
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
m_extendedActiveEndpointListAvailable = ((descriptorFlag >> 0) & 0x01);
|
||||||
reply->deleteLater();
|
m_extendedSimpleDescriptorListAvailable = ((descriptorFlag >> 1) & 0x01);
|
||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
|
||||||
qCDebug(dcZigbeeController()) << reply->additionalMessage();
|
|
||||||
|
|
||||||
quint8 sequenceNumber = static_cast<quint8>(reply->additionalMessage().data().at(0));
|
|
||||||
quint8 status = static_cast<quint8>(reply->additionalMessage().data().at(1));
|
|
||||||
|
|
||||||
quint16 nwkAddress = reply->additionalMessage().data().at(2);
|
|
||||||
nwkAddress <<= 8;
|
|
||||||
nwkAddress |= reply->additionalMessage().data().at(3);
|
|
||||||
|
|
||||||
quint8 length = static_cast<quint8>(reply->additionalMessage().data().at(4));
|
|
||||||
|
|
||||||
if (length == 0) {
|
|
||||||
qCWarning(dcZigbee()) << "Length 0";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint8 endPoint = static_cast<quint8>(reply->additionalMessage().data().at(5));
|
|
||||||
|
|
||||||
quint16 profileId = reply->additionalMessage().data().at(6);
|
|
||||||
profileId <<= 8;
|
|
||||||
profileId |= reply->additionalMessage().data().at(7);
|
|
||||||
|
|
||||||
quint16 deviceId = reply->additionalMessage().data().at(8);
|
|
||||||
deviceId <<= 8;
|
|
||||||
deviceId |= reply->additionalMessage().data().at(9);
|
|
||||||
|
|
||||||
quint8 bitField = static_cast<quint8>(reply->additionalMessage().data().at(10));
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << "Node simple descriptor:";
|
|
||||||
qCDebug(dcZigbee()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber);
|
|
||||||
qCDebug(dcZigbee()) << " Status:" << ZigbeeUtils::convertByteToHexString(status);
|
|
||||||
qCDebug(dcZigbee()) << " Nwk address:" << ZigbeeUtils::convertUint16ToHexString(nwkAddress);
|
|
||||||
qCDebug(dcZigbee()) << " Lenght:" << ZigbeeUtils::convertByteToHexString(length);
|
|
||||||
qCDebug(dcZigbee()) << " End Point:" << ZigbeeUtils::convertByteToHexString(endPoint);
|
|
||||||
qCDebug(dcZigbee()) << " Profile:" << ZigbeeUtils::profileIdToString((Zigbee::ZigbeeProfile)profileId);
|
|
||||||
|
|
||||||
if (profileId == Zigbee::ZigbeeProfileLightLink) {
|
|
||||||
qCDebug(dcZigbee()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::LightLinkDevice>(deviceId);
|
|
||||||
} else {
|
|
||||||
qCDebug(dcZigbee()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::HomeAutomationDevice>(deviceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << " Bit field:" << ZigbeeUtils::convertByteToHexString(bitField);
|
|
||||||
|
|
||||||
quint8 inputClusterCount = static_cast<quint8>(reply->additionalMessage().data().at(10));
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << " Input clusters:";
|
|
||||||
QByteArray inputClusterListData = reply->additionalMessage().data().mid(11, inputClusterCount * 2);
|
|
||||||
for (int i = 0; i < inputClusterListData.count(); i+=2) {
|
|
||||||
quint16 clusterId = inputClusterListData.at(i);
|
|
||||||
clusterId <<= 8;
|
|
||||||
clusterId |= inputClusterListData .at(i+1);
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
|
|
||||||
}
|
|
||||||
|
|
||||||
quint8 outputClusterCount = static_cast<quint8>(reply->additionalMessage().data().at(12 + inputClusterCount * 2));
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << " Output clusters:";
|
|
||||||
QByteArray outputClusterListData = reply->additionalMessage().data().mid(12 + inputClusterCount * 2, outputClusterCount * 2);
|
|
||||||
for (int i = 0; i < outputClusterListData.count(); i+=2) {
|
|
||||||
quint16 clusterId = outputClusterListData.at(i);
|
|
||||||
clusterId <<= 8;
|
|
||||||
clusterId |= outputClusterListData .at(i+1);
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNode::onRequestPowerDescriptorFinished()
|
//void ZigbeeNode::onRequestUserDescriptorFinished()
|
||||||
{
|
//{
|
||||||
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
// ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
||||||
reply->deleteLater();
|
// reply->deleteLater();
|
||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
// if (reply->status() != ZigbeeInterfaceReply::Success) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
// qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
// qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
||||||
qCDebug(dcZigbeeController()) << reply->additionalMessage();
|
// qCDebug(dcZigbeeController()) << reply->additionalMessage();
|
||||||
|
|
||||||
quint8 sequenceNumber = static_cast<quint8>(reply->additionalMessage().data().at(0));
|
// quint8 sequenceNumber = static_cast<quint8>(reply->additionalMessage().data().at(0));
|
||||||
quint8 status = static_cast<quint8>(reply->additionalMessage().data().at(1));
|
// quint8 status = static_cast<quint8>(reply->additionalMessage().data().at(1));
|
||||||
|
|
||||||
quint16 bitField = reply->additionalMessage().data().at(2);
|
// quint16 nwkAddress = static_cast<quint16>(reply->additionalMessage().data().at(2));
|
||||||
bitField <<= 8;
|
// nwkAddress <<= 8;
|
||||||
bitField |= reply->additionalMessage().data().at(3);
|
// nwkAddress |= reply->additionalMessage().data().at(3);
|
||||||
|
|
||||||
// Bit 0 - 3 Power mode
|
// quint8 length = static_cast<quint8>(reply->additionalMessage().data().at(4));
|
||||||
// 0000: Receiver configured according to “Receiver on when idle” MAC flag in the Node Descriptor
|
|
||||||
// 0001: Receiver switched on periodically
|
|
||||||
// 0010: Receiver switched on when stimulated, e.g. by pressing a button
|
|
||||||
|
|
||||||
if (!ZigbeeUtils::checkBitUint16(bitField, 0) && !ZigbeeUtils::checkBitUint16(bitField, 1)) {
|
// QByteArray data;
|
||||||
m_powerMode = PowerModeAlwaysOn;
|
// if (length > 0) {
|
||||||
} else if (ZigbeeUtils::checkBitUint16(bitField, 0) && !ZigbeeUtils::checkBitUint16(bitField, 1)) {
|
// data = reply->additionalMessage().data().mid(5, length);
|
||||||
m_powerMode = PowerModeOnPeriodically;
|
// }
|
||||||
} else if (!ZigbeeUtils::checkBitUint16(bitField, 0) && ZigbeeUtils::checkBitUint16(bitField, 1)) {
|
|
||||||
m_powerMode = PowerModeOnWhenStimulated;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bit 4 - 7 Available power sources
|
// qCDebug(dcZigbeeNetwork()) << "User descriptor:";
|
||||||
// Bit 0: Permanent mains supply
|
// qCDebug(dcZigbeeNetwork()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber);
|
||||||
// Bit 1: Rechargeable battery
|
// qCDebug(dcZigbeeNetwork()) << " Status:" << ZigbeeUtils::convertByteToHexString(status);
|
||||||
// Bit 2: Disposable battery
|
// qCDebug(dcZigbeeNetwork()) << " Attribute address:" << ZigbeeUtils::convertUint16ToHexString(nwkAddress);
|
||||||
// Bit 4: Reserved
|
// qCDebug(dcZigbeeNetwork()) << " Lenght:" << ZigbeeUtils::convertByteToHexString(length);
|
||||||
|
// qCDebug(dcZigbeeNetwork()) << " Data:" << data;
|
||||||
|
//}
|
||||||
|
|
||||||
if (ZigbeeUtils::checkBitUint16(bitField, 4)) {
|
//void ZigbeeNode::onToggleFinished()
|
||||||
m_availablePowerSources.append(PowerSourcePermanentMainSupply);
|
//{
|
||||||
} else if (ZigbeeUtils::checkBitUint16(bitField, 5)) {
|
// ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
||||||
m_availablePowerSources.append(PowerSourceRecharchableBattery);
|
// reply->deleteLater();
|
||||||
} else if (ZigbeeUtils::checkBitUint16(bitField, 6)) {
|
|
||||||
m_availablePowerSources.append(PowerSourceDisposableBattery);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bit 8 - 11 Active source: according to the same schema as available power sources
|
// if (reply->status() != ZigbeeInterfaceReply::Success) {
|
||||||
if (ZigbeeUtils::checkBitUint16(bitField, 8)) {
|
// qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
||||||
m_powerSource = PowerSourcePermanentMainSupply;
|
// return;
|
||||||
} else if (ZigbeeUtils::checkBitUint16(bitField, 9)) {
|
// }
|
||||||
m_powerSource = PowerSourceRecharchableBattery;
|
|
||||||
} else if (ZigbeeUtils::checkBitUint16(bitField, 10)) {
|
|
||||||
m_powerSource = PowerSourceDisposableBattery;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bit 12 - 15: Battery level if available
|
// qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
||||||
// 0000: Critically low
|
//}
|
||||||
// 0100: Approximately 33%
|
|
||||||
// 1000: Approximately 66%
|
|
||||||
// 1100: Approximately 100% (near fully charged)
|
|
||||||
|
|
||||||
if (!ZigbeeUtils::checkBitUint16(bitField, 14) && !ZigbeeUtils::checkBitUint16(bitField, 15)) {
|
//void ZigbeeNode::onIdentifyFinished()
|
||||||
m_powerLevel = PowerLevelCriticalLow;
|
//{
|
||||||
} else if (ZigbeeUtils::checkBitUint16(bitField, 14) && !ZigbeeUtils::checkBitUint16(bitField, 15)) {
|
|
||||||
m_powerLevel = PowerLevelLow;
|
|
||||||
} else if (!ZigbeeUtils::checkBitUint16(bitField, 14) && ZigbeeUtils::checkBitUint16(bitField, 15)) {
|
|
||||||
m_powerLevel = PowerLevelOk;
|
|
||||||
} else if (ZigbeeUtils::checkBitUint16(bitField, 14) && ZigbeeUtils::checkBitUint16(bitField, 15)) {
|
|
||||||
m_powerLevel = PowerLevelFull;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << "Node power descriptor:";
|
|
||||||
qCDebug(dcZigbee()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber);
|
|
||||||
qCDebug(dcZigbee()) << " Status:" << ZigbeeUtils::convertByteToHexString(status);
|
|
||||||
qCDebug(dcZigbee()) << " Bitfiled:" << ZigbeeUtils::convertUint16ToHexString(bitField);
|
|
||||||
qCDebug(dcZigbee()) << " Power mode:" << m_powerMode;
|
|
||||||
qCDebug(dcZigbee()) << " Available power sources:";
|
|
||||||
foreach (const PowerSource &source, m_availablePowerSources) {
|
|
||||||
qCDebug(dcZigbee()) << " " << source;
|
|
||||||
}
|
|
||||||
qCDebug(dcZigbee()) << " Power source:" << m_powerSource;
|
|
||||||
qCDebug(dcZigbee()) << " Power level:" << m_powerLevel;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNode::onRequestUserDescriptorFinished()
|
|
||||||
{
|
|
||||||
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
|
||||||
reply->deleteLater();
|
|
||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
|
||||||
qCDebug(dcZigbeeController()) << reply->additionalMessage();
|
|
||||||
|
|
||||||
quint8 sequenceNumber = static_cast<quint8>(reply->additionalMessage().data().at(0));
|
|
||||||
quint8 status = static_cast<quint8>(reply->additionalMessage().data().at(1));
|
|
||||||
|
|
||||||
quint16 nwkAddress = reply->additionalMessage().data().at(2);
|
|
||||||
nwkAddress <<= 8;
|
|
||||||
nwkAddress |= reply->additionalMessage().data().at(3);
|
|
||||||
|
|
||||||
quint8 length = static_cast<quint8>(reply->additionalMessage().data().at(4));
|
|
||||||
|
|
||||||
QByteArray data;
|
|
||||||
if (length > 0) {
|
|
||||||
data = reply->additionalMessage().data().mid(5, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbee()) << "User descriptor:";
|
|
||||||
qCDebug(dcZigbee()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber);
|
|
||||||
qCDebug(dcZigbee()) << " Status:" << ZigbeeUtils::convertByteToHexString(status);
|
|
||||||
qCDebug(dcZigbee()) << " Attribute address:" << ZigbeeUtils::convertUint16ToHexString(nwkAddress);
|
|
||||||
qCDebug(dcZigbee()) << " Lenght:" << ZigbeeUtils::convertByteToHexString(length);
|
|
||||||
qCDebug(dcZigbee()) << " Data:" << data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNode::onToggleFinished()
|
|
||||||
{
|
|
||||||
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
|
||||||
reply->deleteLater();
|
|
||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNode::onIdentifyFinished()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
//}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, ZigbeeNode *node)
|
QDebug operator<<(QDebug debug, ZigbeeNode *node)
|
||||||
{
|
{
|
||||||
debug.nospace().noquote() << "Node(" << ZigbeeUtils::convertUint16ToHexString(node->shortAddress()) << " | " << node->extendedAddress().toString() << ") ";
|
debug.nospace().noquote() << "ZigbeeNode(" << ZigbeeUtils::convertUint16ToHexString(node->shortAddress()) << ", " << node->extendedAddress().toString() << ") ";
|
||||||
debug.nospace().noquote() << " " << ZigbeeUtils::convertUint16ToHexString(node->shortAddress()) << " | " << node->extendedAddress().toString() << ") ";
|
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,9 +5,6 @@
|
|||||||
|
|
||||||
#include "zigbee.h"
|
#include "zigbee.h"
|
||||||
#include "zigbeeaddress.h"
|
#include "zigbeeaddress.h"
|
||||||
#include "zigbeebridgecontroller.h"
|
|
||||||
|
|
||||||
class ZigbeeNetworkManager;
|
|
||||||
|
|
||||||
class ZigbeeNode : public QObject
|
class ZigbeeNode : public QObject
|
||||||
{
|
{
|
||||||
@ -30,6 +27,12 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(FrequencyBand)
|
Q_ENUM(FrequencyBand)
|
||||||
|
|
||||||
|
enum DeviceType {
|
||||||
|
DeviceTypeFullFunction,
|
||||||
|
DeviceTypeReducedFunction
|
||||||
|
};
|
||||||
|
Q_ENUM(DeviceType)
|
||||||
|
|
||||||
enum Relationship {
|
enum Relationship {
|
||||||
Parent,
|
Parent,
|
||||||
Child,
|
Child,
|
||||||
@ -59,44 +62,56 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(PowerLevel)
|
Q_ENUM(PowerLevel)
|
||||||
|
|
||||||
|
ZigbeeNode(QObject *parent = nullptr);
|
||||||
|
|
||||||
quint16 shortAddress() const;
|
quint16 shortAddress() const;
|
||||||
ZigbeeAddress extendedAddress() const;
|
ZigbeeAddress extendedAddress() const;
|
||||||
int endPoint() const;
|
quint8 endPoint() const;
|
||||||
|
|
||||||
// Information from node descriptor
|
// Information from node descriptor
|
||||||
NodeType nodeType() const;
|
NodeType nodeType() const;
|
||||||
FrequencyBand frequencyBand() const;
|
FrequencyBand frequencyBand() const;
|
||||||
Relationship relationShip() const;
|
Relationship relationship() const;
|
||||||
Zigbee::ZigbeeProfile profile() const;
|
Zigbee::ZigbeeProfile profile() const;
|
||||||
quint16 manufacturerCode() const;
|
quint16 manufacturerCode() const;
|
||||||
|
|
||||||
|
bool complexDescriptorAvailable() const;
|
||||||
|
bool userDescriptorAvailable() const;
|
||||||
|
|
||||||
|
quint16 maximumRxSize() const;
|
||||||
|
quint16 maximumTxSize() const;
|
||||||
|
quint8 maximumBufferSize() const;
|
||||||
|
|
||||||
|
// Information from node power descriptor
|
||||||
PowerMode powerMode() const;
|
PowerMode powerMode() const;
|
||||||
PowerSource powerSource() const;
|
PowerSource powerSource() const;
|
||||||
QList<PowerSource> availablePowerSources() const;
|
QList<PowerSource> availablePowerSources() const;
|
||||||
PowerLevel powerLevel() const;
|
PowerLevel powerLevel() const;
|
||||||
|
|
||||||
// Node specific zigbee commands
|
// Node specific zigbee commands
|
||||||
void init();
|
// void init();
|
||||||
void identify();
|
// void identify();
|
||||||
void toggle(int addressMode);
|
// void toggle(int addressMode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeBridgeController *m_controller;
|
|
||||||
|
|
||||||
quint16 m_shortAddress = 0;
|
quint16 m_shortAddress = 0;
|
||||||
ZigbeeAddress m_extendedAddress;
|
ZigbeeAddress m_extendedAddress;
|
||||||
int m_endPoint = 0;
|
quint8 m_endPoint = 1;
|
||||||
|
|
||||||
NodeType m_nodeType = NodeTypeRouter;
|
NodeType m_nodeType = NodeTypeRouter;
|
||||||
FrequencyBand m_frequencyBand = FrequencyBand2400Mhz;
|
FrequencyBand m_frequencyBand = FrequencyBand2400Mhz;
|
||||||
Relationship m_relationShip = Parent;
|
Relationship m_relationship = Parent;
|
||||||
|
|
||||||
Zigbee::ZigbeeProfile m_profile;
|
Zigbee::ZigbeeProfile m_profile;
|
||||||
quint16 m_manufacturerCode = 0;
|
quint16 m_manufacturerCode = 0;
|
||||||
|
|
||||||
quint16 m_maximalRxSize = 0;
|
bool m_complexDescriptorAvailable = false;
|
||||||
quint16 m_maximalTxSize = 0;
|
bool m_userDescriptorAvailable = false;
|
||||||
|
|
||||||
|
quint16 m_maximumRxSize = 0;
|
||||||
|
quint16 m_maximumTxSize = 0;
|
||||||
|
quint8 m_maximumBufferSize = 0;
|
||||||
|
|
||||||
|
// Server Mask
|
||||||
bool m_isPrimaryTrustCenter = false;
|
bool m_isPrimaryTrustCenter = false;
|
||||||
bool m_isBackupTrustCenter = false;
|
bool m_isBackupTrustCenter = false;
|
||||||
bool m_isPrimaryBindingCache = false;
|
bool m_isPrimaryBindingCache = false;
|
||||||
@ -111,36 +126,38 @@ private:
|
|||||||
QList<PowerSource> m_availablePowerSources;
|
QList<PowerSource> m_availablePowerSources;
|
||||||
PowerLevel m_powerLevel;
|
PowerLevel m_powerLevel;
|
||||||
|
|
||||||
// Mac capabilities
|
// Mac capabilities flag
|
||||||
|
bool m_alternatePanCoordinator = false;
|
||||||
|
DeviceType m_deviceType = DeviceTypeFullFunction;
|
||||||
|
bool m_powerSourceFlagMainPower = false;
|
||||||
bool m_receiverOnWhenIdle = false;
|
bool m_receiverOnWhenIdle = false;
|
||||||
bool m_securityCapability = false;
|
bool m_securityCapability = false;
|
||||||
|
bool m_allocateAddress = false;
|
||||||
|
|
||||||
void requestNodeDescription();
|
// Descriptor capability
|
||||||
void requestSimpleNodeDescription();
|
bool m_extendedActiveEndpointListAvailable = false;
|
||||||
void requestPowerDescriptor();
|
bool m_extendedSimpleDescriptorListAvailable = false;
|
||||||
void requestUserDescriptor();
|
|
||||||
|
|
||||||
void saveToSettings();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ZigbeeNode(ZigbeeBridgeController *controller, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
ZigbeeBridgeController *controller();
|
|
||||||
|
|
||||||
void setShortAddress(const quint16 &shortAddress);
|
void setShortAddress(const quint16 &shortAddress);
|
||||||
void setExtendedAddress(const ZigbeeAddress &extendedAddress);
|
void setExtendedAddress(const ZigbeeAddress &extendedAddress);
|
||||||
|
void setEndPoint(quint8 endPoint);
|
||||||
|
|
||||||
signals:
|
void setNodeType(NodeType nodeType);
|
||||||
|
void setFrequencyBand(FrequencyBand frequencyBand);
|
||||||
|
void setRelationship(Relationship relationship);
|
||||||
|
void setZigbeeProfile(Zigbee::ZigbeeProfile profile);
|
||||||
|
void setManufacturerCode(quint16 manufacturerCode);
|
||||||
|
|
||||||
private slots:
|
void setMaximumRxSize(quint16 size);
|
||||||
void onRequestNodeDescriptionFinished();
|
void setMaximumTxSize(quint16 size);
|
||||||
void onRequestSimpleNodeDescriptionFinished();
|
void setMaximumBufferSize(quint8 size);
|
||||||
void onRequestPowerDescriptorFinished();
|
|
||||||
void onRequestUserDescriptorFinished();
|
|
||||||
void onToggleFinished();
|
|
||||||
void onIdentifyFinished();
|
|
||||||
|
|
||||||
public slots:
|
void setServerMask(quint16 serverMask);
|
||||||
|
void setComplexDescriptorAvailable(bool complexDescriptorAvailable);
|
||||||
|
void setUserDescriptorAvailable(bool userDescriptorAvailable);
|
||||||
|
void setMacCapabilitiesFlag(quint16 macFlag);
|
||||||
|
void setDescriptorFlag(quint8 descriptorFlag);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
26
libnymea-zigbee/zigbeesecurityconfiguration.cpp
Normal file
26
libnymea-zigbee/zigbeesecurityconfiguration.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "zigbeesecurityconfiguration.h"
|
||||||
|
|
||||||
|
ZigbeeSecurityConfiguration::ZigbeeSecurityConfiguration()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ZigbeeSecurityConfiguration::networkKey() const
|
||||||
|
{
|
||||||
|
return m_networkKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeSecurityConfiguration::setNetworkKey(const QString &networkKey)
|
||||||
|
{
|
||||||
|
m_networkKey = networkKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ZigbeeSecurityConfiguration::globalTrustCenterLinkKey() const
|
||||||
|
{
|
||||||
|
return m_globalTrustCenterLinkKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeSecurityConfiguration::setGlobalTrustCenterlinkKey(const QString &globalTrustCenterLinkKey)
|
||||||
|
{
|
||||||
|
m_globalTrustCenterLinkKey = globalTrustCenterLinkKey;
|
||||||
|
}
|
||||||
26
libnymea-zigbee/zigbeesecurityconfiguration.h
Normal file
26
libnymea-zigbee/zigbeesecurityconfiguration.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef ZIGBEESECURITYCONFIGURATION_H
|
||||||
|
#define ZIGBEESECURITYCONFIGURATION_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class ZigbeeSecurityConfiguration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZigbeeSecurityConfiguration();
|
||||||
|
|
||||||
|
QString networkKey() const;
|
||||||
|
void setNetworkKey(const QString &networkKey);
|
||||||
|
|
||||||
|
QString globalTrustCenterLinkKey() const;
|
||||||
|
void setGlobalTrustCenterlinkKey(const QString & globalTrustCenterLinkKey);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This is the local network key
|
||||||
|
QString m_networkKey;
|
||||||
|
|
||||||
|
// Note: this is the zigbee master key from (ZigBeeAlliance09)
|
||||||
|
QString m_globalTrustCenterLinkKey = "5A6967426565416C6C69616E63653039";
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ZIGBEESECURITYCONFIGURATION_H
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#include "zigbeeutils.h"
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ QByteArray ZigbeeUtils::convertBitArrayToByteArray(const QBitArray &bitArray)
|
|||||||
QByteArray byteArray;
|
QByteArray byteArray;
|
||||||
|
|
||||||
for(int b = 0; b < bitArray.count(); ++b) {
|
for(int b = 0; b < bitArray.count(); ++b) {
|
||||||
byteArray[b / 8] = (byteArray.at( b / 8) | ((bitArray[b] ? 1 : 0) << (7 - ( b % 8))));
|
byteArray[b / 8] = static_cast<char>((byteArray.at( b / 8) | ((bitArray[b] ? 1 : 0) << (7 - ( b % 8)))));
|
||||||
}
|
}
|
||||||
return byteArray;
|
return byteArray;
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ QString ZigbeeUtils::convertByteArrayToHexString(const QByteArray &byteArray)
|
|||||||
{
|
{
|
||||||
QString hexString;
|
QString hexString;
|
||||||
for (int i = 0; i < byteArray.count(); i++) {
|
for (int i = 0; i < byteArray.count(); i++) {
|
||||||
hexString.append(convertByteToHexString((quint8)byteArray.at(i)));
|
hexString.append(convertByteToHexString(static_cast<quint8>(byteArray.at(i))));
|
||||||
if (i != byteArray.count() - 1) {
|
if (i != byteArray.count() - 1) {
|
||||||
hexString.append(" ");
|
hexString.append(" ");
|
||||||
}
|
}
|
||||||
@ -129,3 +130,10 @@ QString ZigbeeUtils::profileIdToString(const Zigbee::ZigbeeProfile &profileId)
|
|||||||
|
|
||||||
return enumString.remove("Zigbee::ZigbeeProfile(ZigbeeProfile").remove(")");
|
return enumString.remove("Zigbee::ZigbeeProfile(ZigbeeProfile").remove(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quint64 ZigbeeUtils::generateRandomPanId()
|
||||||
|
{
|
||||||
|
srand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000));
|
||||||
|
srand(static_cast<uint>(qrand()));
|
||||||
|
return static_cast<quint64>((ULLONG_MAX - 0) * (qrand()/static_cast<double>(RAND_MAX)));
|
||||||
|
}
|
||||||
|
|||||||
@ -32,6 +32,8 @@ public:
|
|||||||
static QString clusterIdToString(const Zigbee::ClusterId &clusterId);
|
static QString clusterIdToString(const Zigbee::ClusterId &clusterId);
|
||||||
static QString profileIdToString(const Zigbee::ZigbeeProfile &profileId);
|
static QString profileIdToString(const Zigbee::ZigbeeProfile &profileId);
|
||||||
|
|
||||||
|
static quint64 generateRandomPanId();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ZIGBEEUTILS_H
|
#endif // ZIGBEEUTILS_H
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
CONFIG += ordered
|
CONFIG += ordered
|
||||||
|
|
||||||
SUBDIRS += libnymea-zigbee zigbee-cli
|
SUBDIRS += libnymea-zigbee #zigbee-cli
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,10 @@ Core::Core(const QString &serialPort, qint32 baudrate, const int &channel, QObje
|
|||||||
m_channelMask = 0;
|
m_channelMask = 0;
|
||||||
m_channelMask |= 1 << (channel);
|
m_channelMask |= 1 << (channel);
|
||||||
|
|
||||||
m_manager = new ZigbeeNetworkManager(channel, m_serialPort, m_baudRate, this);
|
ZigbeeBridgeController *controller = new ZigbeeBridgeController(this);
|
||||||
|
controller->enable(serialPort, baudrate);
|
||||||
|
|
||||||
|
//m_manager = new ZigbeeNetworkManager(channel, controller, this);
|
||||||
|
|
||||||
// Set commands
|
// Set commands
|
||||||
TerminalCommand runCommand("run", "Run the zigbee controller in a normal non interactive mode.");
|
TerminalCommand runCommand("run", "Run the zigbee controller in a normal non interactive mode.");
|
||||||
@ -95,8 +98,8 @@ void Core::onCommandReceived(const QStringList &tokens)
|
|||||||
m_manager->setChannelMask(0x2108800);
|
m_manager->setChannelMask(0x2108800);
|
||||||
m_manager->setDeviceType(nodeType);
|
m_manager->setDeviceType(nodeType);
|
||||||
// Note: this is the leaked philips ZLL master key
|
// Note: this is the leaked philips ZLL master key
|
||||||
m_manager->setInitialSecurity(3, 0, 1, "9F5595F10257C8A469CBF42BC93FEE31");
|
//m_manager->setInitialSecurity(3, 0, 1, "9F5595F10257C8A469CBF42BC93FEE31");
|
||||||
//m_manager->setInitialSecurity(4, 0, 1, "5A6967426565416C6C69616E63653039");
|
m_manager->setInitialSecurity(4, 0, 1, "5A6967426565416C6C69616E63653039");
|
||||||
|
|
||||||
} else if (command.command() == "start") {
|
} else if (command.command() == "start") {
|
||||||
m_manager->startNetwork();
|
m_manager->startNetwork();
|
||||||
|
|||||||
Reference in New Issue
Block a user