From 83b888360aa224dcc89e4ec39d53c77da4a9adef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 25 Oct 2017 21:07:05 +0200 Subject: [PATCH] add firmware and flash script --- core.cpp | 4 +- core.h | 2 +- ...lBridge_JN5168_FULL_FUNC_DEVICE_115200.bin | Bin 0 -> 195228 bytes flash | 84 +++ interface/zigbeeinterface.cpp | 3 + main.cpp | 27 +- qt-zigbee.pro | 2 +- zigbee.cpp | 1 - zigbee.h | 77 ++- zigbeeaddress.cpp | 11 +- zigbeeaddress.h | 1 - zigbeebridgecontroller.cpp | 2 +- zigbeenetworkmanager.cpp | 531 ++++++++---------- zigbeenetworkmanager.h | 27 +- zigbeenode.cpp | 236 +++++++- zigbeenode.h | 37 +- 16 files changed, 701 insertions(+), 344 deletions(-) create mode 100644 firmware/ZigbeeNodeControlBridge_JN5168_FULL_FUNC_DEVICE_115200.bin create mode 100755 flash diff --git a/core.cpp b/core.cpp index 005a29b..f703865 100644 --- a/core.cpp +++ b/core.cpp @@ -1,8 +1,8 @@ #include "core.h" #include -Core::Core(QObject *parent) : +Core::Core(const int &channel, QObject *parent) : QObject(parent) { - m_manager = new ZigbeeNetworkManager("/dev/ttyS0", this); + m_manager = new ZigbeeNetworkManager(channel, "/dev/ttyS0", this); } diff --git a/core.h b/core.h index 39f09df..2045b7c 100644 --- a/core.h +++ b/core.h @@ -9,7 +9,7 @@ class Core : public QObject { Q_OBJECT public: - explicit Core(QObject *parent = nullptr); + explicit Core(const int &channel, QObject *parent = nullptr); private: ZigbeeNetworkManager *m_manager; diff --git a/firmware/ZigbeeNodeControlBridge_JN5168_FULL_FUNC_DEVICE_115200.bin b/firmware/ZigbeeNodeControlBridge_JN5168_FULL_FUNC_DEVICE_115200.bin new file mode 100644 index 0000000000000000000000000000000000000000..167291442018d46be98d9e18806709c3b7e782b2 GIT binary patch literal 195228 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 literal 0 HcmV?d00001 diff --git a/flash b/flash new file mode 100755 index 0000000..c50643b --- /dev/null +++ b/flash @@ -0,0 +1,84 @@ +#!/bin/sh -e + +setProgramMode() { + # Control Pins to put JN516x in bootloader mode + # Pin ZIGBEE_PROGRAM - CSID6 - PE10 (4*32 + 10) = 138 + # Pin ZiGBEE_RESET - CSID7 - PE11 (4*32 + 11) = 139 + echo "Set up program mode for zigbee module" + if [ ! -d /sys/class/gpio/gpio138 ]; then echo 138 > /sys/class/gpio/export; fi + if [ ! -d /sys/class/gpio/gpio139 ]; then echo 139 > /sys/class/gpio/export; fi + + echo "out" > /sys/class/gpio/gpio138/direction + echo "out" > /sys/class/gpio/gpio139/direction + + echo 0 > /sys/class/gpio/gpio138/active_low + echo 1 > /sys/class/gpio/gpio139/active_low + + #resetLow + resetHigh + programHigh + programLow + resetLow +} + +programLow() { + if [ -z "$1" ]; then TIMEOUT=1; else TIMEOUT=$1; fi + echo "Program 0" + echo 0 > /sys/class/gpio/gpio138/value + sleep $TIMEOUT +} + +programHigh() { + if [ -z "$1" ]; then TIMEOUT=1; else TIMEOUT=$1; fi + echo "Program 1" + echo 1 > /sys/class/gpio/gpio138/value + sleep $TIMEOUT +} + +resetLow() { + if [ -z "$1" ]; then TIMEOUT=1; else TIMEOUT=$1; fi + echo "Reset 0" + echo 0 > /sys/class/gpio/gpio139/value + sleep $TIMEOUT +} + +resetHigh() { + if [ -z "$1" ]; then TIMEOUT=1; else TIMEOUT=$1; fi + echo "Reset 1" + echo 1 > /sys/class/gpio/gpio139/value + sleep $TIMEOUT +} + +startFlash() { + if [ $1 ]; then + echo "Start flashing $1 on /dev/ttyS0" + #/usr/bin/JennicModuleProgrammer -I 38400 -P 38400 -s /dev/ttyS0 -f $1 -v -V 3 + /usr/bin/iot_jp -I 38400 -P 38400 -s /dev/ttyS0 -f $1 -v -V 3 + #/usr/bin/iot_jp -I 115200 -P 115200 -s /dev/ttyS0 -f $1 -v -V 3 + result=$? + else + echo "Error: no firmware file passed" + fi +} + +setNormalMode() { + # Control Pins to put JN516x in normal mode + echo "Set up normal mode" +# programLow 0.5 +# resetHigh +# resetLow +} + +cleanup() { + echo "Clean up" + echo 138 > /sys/class/gpio/unexport + # echo 139 > /sys/class/gpio/unexport +} + +setProgramMode +startFlash $1 +setNormalMode +cleanup + +echo "Done" + diff --git a/interface/zigbeeinterface.cpp b/interface/zigbeeinterface.cpp index 6b9e2bf..203c7b7 100644 --- a/interface/zigbeeinterface.cpp +++ b/interface/zigbeeinterface.cpp @@ -17,6 +17,9 @@ ZigbeeInterface::~ZigbeeInterface() bool ZigbeeInterface::available() const { + if (!m_serialPort) + return false; + return m_serialPort->isOpen(); } diff --git a/main.cpp b/main.cpp index 8dd05b9..6e824d8 100644 --- a/main.cpp +++ b/main.cpp @@ -57,6 +57,8 @@ int main(int argc, char *argv[]) qInstallMessageHandler(consoleLogHandler); QCoreApplication application(argc, argv); + application.setOrganizationName("guh"); + application.setApplicationName("qt-zigbee"); // Command line parser QCommandLineParser parser; @@ -64,18 +66,25 @@ int main(int argc, char *argv[]) parser.addVersionOption(); parser.setApplicationDescription(QString("\nDaemon for the zigbee NXP uart bridge.\n\nCopyright %1 2016 Simon Stürz \nAll rights reserved.").arg(QChar(0xA9))); + // Debug level QCommandLineOption debugLevelOption(QStringList() << "d" << "debug-level", "Set debug level [1-4]."); debugLevelOption.setDefaultValue("1"); debugLevelOption.setValueName("level"); parser.addOption(debugLevelOption); + // Channel + QCommandLineOption channelOption(QStringList() << "c" << "channel", "Set channel for the zigbee network. Channel between [11-26] are allowed. If not specified, the quitest channel will be choosen automatically."); + channelOption.setDefaultValue(0); + channelOption.setValueName("channel"); + parser.addOption(channelOption); + parser.process(application); + // Check debug level bool debugLevelValueOk = false; int debugLevel = parser.value(debugLevelOption).toInt(&debugLevelValueOk); - if (debugLevel < 1 || debugLevel > 4 || !debugLevelValueOk) { - qWarning() << "Invalid debug level passed:" << parser.value(debugLevelOption); + qCritical() << "Invalid debug level passed:" << parser.value(debugLevelOption) << "Reset to default debug level 1."; debugLevel = 1; } @@ -86,7 +95,19 @@ int main(int argc, char *argv[]) QLoggingCategory::installFilter(loggingCategoryFilter); - Core core; + // Check channel + bool channelValueOk = false; + int channel = parser.value(channelOption).toInt(&channelValueOk); + if (channel != 0) { + if (channel < 11 || channel > 26 || !channelValueOk) { + qCritical() << "Invalid channel value passed:" << parser.value(channelOption) << "Selecting automatically quitest channel."; + channel = 0; + } + } + + + + Core core(channel); return application.exec(); } diff --git a/qt-zigbee.pro b/qt-zigbee.pro index ddc4ad4..5ae57ca 100644 --- a/qt-zigbee.pro +++ b/qt-zigbee.pro @@ -4,7 +4,7 @@ QT += serialport CONFIG += c++11 console CONFIG -= app_bundle -TARGET = qt-zigbee +TARGET = zigbee-cli target.path = /usr/bin INSTALLS += target diff --git a/zigbee.cpp b/zigbee.cpp index cc23ded..785ed1b 100644 --- a/zigbee.cpp +++ b/zigbee.cpp @@ -1,3 +1,2 @@ #include "zigbee.h" - diff --git a/zigbee.h b/zigbee.h index ee90aad..0c0a326 100644 --- a/zigbee.h +++ b/zigbee.h @@ -3,6 +3,7 @@ #include #include +#include #include class Zigbee @@ -192,11 +193,11 @@ public: // Appliance Statistics Cluster 0x0B03 // http://www.nxp.com/documents/user_manual/JN-UG-3076.pdf - MessageTypeStatisticsClusterLogMessage = 0x0301, // Was 0x0500, was 0x0301 - MessageTypeStatisticsClusterLogMessageResponse = 0x8301, + MessageTypeStatisticsClusterLogMessage = 0x0301, // Was 0x0500, was 0x0301 + MessageTypeStatisticsClusterLogMessageResponse = 0x8301, // IAS Cluster - MessageTypeSendIasZoneEnroolResponse = 0x0400, + MessageTypeSendIasZoneEnroolResponse = 0x0400, MessageTypeIasZoneStatusChangeNotify = 0x8401, // Extended utils @@ -297,9 +298,9 @@ public: LightLinkDeviceColourTemperatureLight = 0x0220, // Controller devices - LightLinkDeviceColourController = 0x8000, - LightLinkDeviceColourSceneController = 0x8010, - LightLinkDeviceNonColourController = 0x8020, + LightLinkDeviceColourController = 0x0800, + LightLinkDeviceColourSceneController = 0x0810, + LightLinkDeviceNonColourController = 0x0820, LightLinkDeviceNonColourSceneController = 0x8030, LightLinkDeviceControlBridge = 0x8040, LightLinkDeviceOnOffSensor = 0x8050 @@ -316,7 +317,7 @@ public: HomeAutomationDeviceDoorLockController = 0x000B, HomeAutomationDeviceSimpleSensor = 0x000C, HomeAutomationDeviceSmartPlug = 0x0051, - HomeAutomationDeviceControlBridge = 0x8040, + HomeAutomationDeviceControlBridge = 0x0840, // Lightning devices HomeAutomationDeviceOnOffLight = 0x0100, @@ -339,9 +340,65 @@ public: }; Q_ENUM(HomeAutomationDevice) - - - + enum DataType { + NoData = 0x00, + Data8 = 0x08, + Data16 = 0x09, + Data24 = 0x0a, + Data32 = 0x0b, + Data40 = 0x0c, + Data48 = 0x0d, + Data56 = 0x0e, + Data64 = 0x0f, + Bool = 0x10, + BitMap8 = 0x18, + BitMap16 = 0x19, + BitMap24 = 0x1a, + BitMap32 = 0x1b, + BitMap40 = 0x1c, + BitMap48 = 0x1d, + BitMap56 = 0x1e, + BitMap64 = 0x1f, + Uint8 = 0x20, + Uint16 = 0x21, + Uint24 = 0x22, + Uint32 = 0x23, + Uint40 = 0x24, + Uint48 = 0x25, + Uint56 = 0x26, + Uint64 = 0x27, + Int8 = 0x28, + Int16 = 0x29, + Int24 = 0x2a, + Int32 = 0x2b, + Int40 = 0x2c, + Int48 = 0x2d, + Int56 = 0x2e, + Int64 = 0x2f, + Enum8 = 0x30, + Enum16 = 0x31, + FloatSemi = 0x38, + FloatSingle = 0x39, + FloatDouble = 0x3a, + OctetString = 0x41, + CharString = 0x42, + LongOctetString = 0x43, + LongCharString = 0x44, + Array = 0x48, + Structure = 0x4c, + Set = 0x50, + Bag = 0x51, + TimeOfDay = 0xe0, + Date = 0xe1, + UtcTime = 0xe2, + Cluster = 0xe8, + Attribute = 0xe9, + BacnetId = 0xea, + IeeeAddress = 0xf0, + BitKey128 = 0xf1, + Unknown = 0xff + }; + Q_ENUM(DataType) ///* Manufacturer Codes */ ///* Codes less than 0x1000 were issued for RF4CE */ diff --git a/zigbeeaddress.cpp b/zigbeeaddress.cpp index e66d7b0..9b05917 100644 --- a/zigbeeaddress.cpp +++ b/zigbeeaddress.cpp @@ -34,11 +34,6 @@ ZigbeeAddress::ZigbeeAddress(const ZigbeeAddress &other) m_address = other.toUInt64(); } -ZigbeeAddress::~ZigbeeAddress() -{ - -} - quint64 ZigbeeAddress::toUInt64() const { return m_address; @@ -66,6 +61,12 @@ void ZigbeeAddress::clear() m_address = 0; } +ZigbeeAddress &ZigbeeAddress::operator=(const ZigbeeAddress &other) +{ + m_address = other.toUInt64(); + return *this; +} + bool ZigbeeAddress::operator<(const ZigbeeAddress &other) const { return m_address < other.toUInt64(); diff --git a/zigbeeaddress.h b/zigbeeaddress.h index 9af9bba..5589ba7 100644 --- a/zigbeeaddress.h +++ b/zigbeeaddress.h @@ -11,7 +11,6 @@ public: explicit ZigbeeAddress(quint64 address); explicit ZigbeeAddress(const QString &address); ZigbeeAddress(const ZigbeeAddress &other); - ~ZigbeeAddress(); quint64 toUInt64() const; QString toString() const; diff --git a/zigbeebridgecontroller.cpp b/zigbeebridgecontroller.cpp index 1fa290e..008cf09 100644 --- a/zigbeebridgecontroller.cpp +++ b/zigbeebridgecontroller.cpp @@ -9,7 +9,7 @@ ZigbeeBridgeController::ZigbeeBridgeController(const QString &serialPort, QObjec connect(m_interface, &ZigbeeInterface::messageReceived, this, &ZigbeeBridgeController::onMessageReceived); if (!m_interface->enable(serialPort)) { - qCWarning(dcZigbeeController()) << "Could not enable ZigbeeInterface on" << serialPort; + qCCritical(dcZigbeeController()) << "Could not enable ZigbeeInterface on" << serialPort; return; } } diff --git a/zigbeenetworkmanager.cpp b/zigbeenetworkmanager.cpp index d583890..3d000c2 100644 --- a/zigbeenetworkmanager.cpp +++ b/zigbeenetworkmanager.cpp @@ -4,28 +4,57 @@ #include #include +#include -ZigbeeNetworkManager::ZigbeeNetworkManager(const QString &serialPort, QObject *parent) : - ZigbeeNode(parent), - m_serialPort(serialPort) +ZigbeeNetworkManager::ZigbeeNetworkManager(const int &channel, const QString &serialPort, QObject *parent) : + ZigbeeNode(new ZigbeeBridgeController(serialPort, parent), parent) { - // TODO: load PAN id and serial port - reset(); + connect(controller(), &ZigbeeBridgeController::messageReceived, this, &ZigbeeNetworkManager::onMessageReceived); -} + if (controller()->available()) { + qCDebug(dcZigbee()) << "Bridge controller started successfully on" << serialPort; + } else { + qCCritical(dcZigbee()) << "The zigbee controller is not available on" << serialPort; + //return; + } -QString ZigbeeNetworkManager::serialPort() const -{ - return m_serialPort; -} + QSettings settings; + settings.beginGroup("Network"); + m_extendedPanId = static_cast(settings.value("panId", 0).toUInt()); + if (m_extendedPanId == 0) { + m_extendedPanId = generateRandomPanId(); + settings.setValue("panId", m_extendedPanId); + } + settings.endGroup(); -void ZigbeeNetworkManager::setSerialPort(const QString &serialPort) -{ - if (m_serialPort == serialPort) - return; + qCDebug(dcZigbee()) << "PAN Id:" << m_extendedPanId << ZigbeeUtils::convertUint64ToHexString(m_extendedPanId); + + // Create channel mask + // Note: normal number passed, that specific channel will be used || Bitfield: all channels would be 0x07FFF800 + quint32 channelMask = 0; + if (channel == 0) { + qCDebug(dcZigbee()) << "Using quitest channel for the zigbee network."; + } else { + channelMask |= 1 << (channel); + qCDebug(dcZigbee()) << "Using channel" << channel << "for the zigbee network."; + } + + // Call init methods + erasePersistentData(); + //resetController(); + getVersion(); + setExtendedPanId(m_extendedPanId); + setChannelMask(channelMask); + setDeviceType(NodeTypeCoordinator); + startNetwork(); + + + //startScan(); + //getPermitJoiningStatus(); + enableWhitelist(); + permitJoining(); + //getPermitJoiningStatus(); - m_serialPort = serialPort; - reset(); } QString ZigbeeNetworkManager::controllerVersion() const @@ -33,38 +62,14 @@ QString ZigbeeNetworkManager::controllerVersion() const return m_controllerVersion; } +QList ZigbeeNetworkManager::nodeList() const +{ + return m_nodeList; +} + void ZigbeeNetworkManager::reset() { - if (m_controller) { - delete m_controller; - m_controller = nullptr; - } - - //m_extendedPanId = generateRandomPanId(); - m_extendedPanId = 1180461015847120384; - qCDebug(dcZigbee()) << "PAN ID" << m_extendedPanId; - - m_controller = new ZigbeeBridgeController(m_serialPort, this); - connect(m_controller, &ZigbeeBridgeController::messageReceived, this, &ZigbeeNetworkManager::onMessageReceived); - - if (m_controller->available()) { - qCDebug(dcZigbee()) << "Bridge controller started successfully on" << m_serialPort; - } else { - qCWarning(dcZigbee()) << "The zigbee controller is not available"; - } - - // Call init methods - erasePersistentData(); - //reset(); - getVersion(); - setExtendedPanId(m_extendedPanId); - setChannelMask(0); - setDeviceType(NodeTypeCoordinator); - startNetwork(); - //startScan(); - //getPermitJoiningStatus(); - permitJoining(); - //getPermitJoiningStatus(); + qCCritical(dcZigbee()) << "Reset networkmanager: TODO: needs to be implementet"; } quint64 ZigbeeNetworkManager::generateRandomPanId() @@ -74,12 +79,44 @@ quint64 ZigbeeNetworkManager::generateRandomPanId() return (ULLONG_MAX - 0) * (qrand()/(double)RAND_MAX); } +void ZigbeeNetworkManager::loadNetwork() +{ + qCDebug(dcZigbee()) << "Loading network nodes"; + QSettings settings; + settings.beginGroup("Nodes"); + foreach (const QString nodeAddress, settings.childGroups()) { + settings.beginGroup(nodeAddress); + quint16 shortAddress = static_cast(settings.value("shortAddress", 0).toUInt()); + settings.endGroup(); + + ZigbeeNode *node = new ZigbeeNode(controller(), this); + node->setExtendedAddress(ZigbeeAddress(nodeAddress)); + node->setShortAddress(shortAddress); + m_nodeList.append(node); + node->init(); + } + +} + +void ZigbeeNetworkManager::saveNetwork() +{ + qCDebug(dcZigbee()) << "Save network"; + QSettings settings; + settings.beginGroup("Nodes"); + foreach (ZigbeeNode *node, m_nodeList) { + settings.beginGroup(node->extendedAddress().toString()); + settings.setValue("shortAddress", node->shortAddress()); + settings.endGroup(); + } +} + void ZigbeeNetworkManager::resetController() { ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeReset)); request.setDescription("Reset controller"); + request.setTimoutIntervall(3000); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onResetControllerFinished); } @@ -88,7 +125,7 @@ void ZigbeeNetworkManager::erasePersistentData() ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeErasePersistentData)); request.setDescription("Erase persistent data"); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onErasePersistentDataFinished); } @@ -101,7 +138,7 @@ void ZigbeeNetworkManager::sendDataManagerAvailableResponse() ZigbeeInterfaceRequest request(message); request.setDescription("Data manager available response"); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, reply, &ZigbeeInterfaceReply::deleteLater); } @@ -111,7 +148,7 @@ void ZigbeeNetworkManager::getVersion() request.setDescription("Get version"); request.setExpectedAdditionalMessageType(Zigbee::MessageTypeVersionList); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onGetVersionFinished); } @@ -124,7 +161,7 @@ void ZigbeeNetworkManager::setExtendedPanId(const quint64 &panId) ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSetExtendetPanId, data)); request.setDescription("Set extended PAN ID " + QString::number(panId) + " " + ZigbeeUtils::convertUint64ToHexString(panId)); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onSetExtendedPanIdFinished); } @@ -137,7 +174,7 @@ void ZigbeeNetworkManager::setChannelMask(const quint32 &channelMask) ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSetChannelMask, data)); request.setDescription("Set channel mask " + ZigbeeUtils::convertByteArrayToHexString(data)); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onSetChannelMaskFinished); } @@ -152,7 +189,7 @@ void ZigbeeNetworkManager::setDeviceType(const NodeType &deviceType) ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeSetDeviceType, data)); request.setDescription("Set device type"); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onSetDeviceTypeFinished); } @@ -163,7 +200,7 @@ void ZigbeeNetworkManager::startNetwork() request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNetworkJoinedFormed); request.setTimoutIntervall(12000); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onStartNetworkFinished); } @@ -174,7 +211,7 @@ void ZigbeeNetworkManager::startScan() request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNetworkJoinedFormed); request.setTimoutIntervall(12000); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onStartScanFinished); } @@ -188,7 +225,7 @@ void ZigbeeNetworkManager::permitJoining(quint16 targetAddress, const quint8 adv ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypePermitJoiningRequest, data)); request.setDescription("Permit joining request on " + ZigbeeUtils::convertUint16ToHexString(targetAddress) + " for " + QString::number(advertisingIntervall) + "[s]"); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onPermitJoiningFinished); } @@ -199,54 +236,17 @@ void ZigbeeNetworkManager::getPermitJoiningStatus() request.setExpectedAdditionalMessageType(Zigbee::MessageTypeGetPermitJoiningResponse); request.setTimoutIntervall(1000); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onGetPermitJoiningStatusFinished); } -void ZigbeeNetworkManager::requestNodeDescription(const quint16 &shortAddress) +void ZigbeeNetworkManager::enableWhitelist() { - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - stream << shortAddress; + ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeNetworkWhitelistEnable)); + request.setDescription("Enable whitelist"); - ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeNodeDescriptorRequest, data)); - request.setExpectedAdditionalMessageType(Zigbee::MessageTypeNodeDescriptorRsponse); - request.setDescription("Node descriptor request for " + ZigbeeUtils::convertUint16ToHexString(shortAddress)); - request.setTimoutIntervall(10000); - - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onRequestNodeDescriptionFinished); -} - -void ZigbeeNetworkManager::requestSimpleNodeDescription(const quint16 &shortAddress, const 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)); - request.setTimoutIntervall(10000); - - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onRequestSimpleNodeDescriptionFinished); -} - -void ZigbeeNetworkManager::requestPowerDescriptor(const 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(10000); - - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onRequestPowerDescriptorFinished); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); + connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onEnableWhitelistFinished); } void ZigbeeNetworkManager::requestMatchDescriptor(const quint16 &shortAddress, const Zigbee::ZigbeeProfile &profile) @@ -255,15 +255,25 @@ void ZigbeeNetworkManager::requestMatchDescriptor(const quint16 &shortAddress, c QDataStream stream(&data, QIODevice::WriteOnly); stream << shortAddress; stream << static_cast(profile); - stream << static_cast(0); - stream << static_cast(0); - ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypePowerDescriptorRequest, data)); - request.setExpectedAdditionalMessageType(Zigbee::MessageTypePowerDescriptorResponse); + // TODO: check what this does + +// // Input clusters +// stream << static_cast(7); +// stream << static_cast(Zigbee::ClusterIdBasic); +// stream << static_cast(Zigbee::ClusterIdIdentify); +// stream << static_cast(Zigbee::ClusterIdGroups); +// stream << static_cast(Zigbee::ClusterIdScenes); +// stream << static_cast(Zigbee::ClusterIdOnOff); +// stream << static_cast(Zigbee::ClusterIdLevelControl); +// stream << static_cast(Zigbee::ClusterIdColorControl); + + ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeMatchDescriptorRequest, data)); + request.setExpectedAdditionalMessageType(Zigbee::MessageTypeMatchDescriptorResponse); request.setDescription("Request match descriptors " + ZigbeeUtils::convertUint16ToHexString(shortAddress)); - request.setTimoutIntervall(10000); + request.setTimoutIntervall(5000); - ZigbeeInterfaceReply *reply = m_controller->sendRequest(request); + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onRequestMatchDescriptorFinished); } @@ -418,18 +428,16 @@ void ZigbeeNetworkManager::onStartNetworkFinished() qCDebug(dcZigbee()).noquote() << "Network" << networkStatusString; qCDebug(dcZigbee()) << " Address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress); - qCDebug(dcZigbee()) << " Extended address:" << ZigbeeUtils::convertUint64ToHexString(extendedAddress) << ZigbeeAddress(extendedAddress) << ZigbeeAddress(extendedAddress).toUInt64(); + qCDebug(dcZigbee()) << " Extended address:" << ZigbeeAddress(extendedAddress); qCDebug(dcZigbee()) << " Channel:" << channel; // Set the node information setShortAddress(shortAddress); - setExtendedAddress(extendedAddress); + setExtendedAddress(ZigbeeAddress(extendedAddress)); - // Request data - requestNodeDescription(shortAddress); - requestSimpleNodeDescription(shortAddress); - requestPowerDescriptor(shortAddress); + init(); + loadNetwork(); } void ZigbeeNetworkManager::onStartScanFinished() @@ -471,174 +479,33 @@ void ZigbeeNetworkManager::onPermitJoiningFinished() } qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; - -} - -void ZigbeeNetworkManager::onRequestNodeDescriptionFinished() -{ - ZigbeeInterfaceReply *reply = static_cast(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"; - - quint8 sequenceNumber = static_cast(reply->additionalMessage().data().at(0)); - quint8 status = static_cast(reply->additionalMessage().data().at(1)); - - quint16 shortAddress = reply->additionalMessage().data().at(2); - shortAddress <<= 8; - shortAddress |= reply->additionalMessage().data().at(3); - - quint16 manufacturerCode = reply->additionalMessage().data().at(4); - 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(reply->additionalMessage().data().at(12)); - quint8 macFlags = static_cast(reply->additionalMessage().data().at(13)); - quint8 maxBufferSize = static_cast(reply->additionalMessage().data().at(14)); - - quint16 bitField = reply->additionalMessage().data().at(15); - bitField <<= 8; - bitField |= reply->additionalMessage().data().at(16); - - // TODO: find node for short address and set data - - qCDebug(dcZigbee()) << "Node descriptor:"; - 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(maximalRxSize); - qCDebug(dcZigbee()) << " Maximum Tx size:" << ZigbeeUtils::convertUint16ToHexString(maximalTxSize); - qCDebug(dcZigbee()) << " Server makk:" << ZigbeeUtils::convertUint16ToHexString(serverMask); - qCDebug(dcZigbee()) << " Descriptor flag:" << ZigbeeUtils::convertByteToHexString(descriptorFlag); - qCDebug(dcZigbee()) << " MAC flags:" << ZigbeeUtils::convertByteToHexString(macFlags); - qCDebug(dcZigbee()) << " Maximum buffer size:" << ZigbeeUtils::convertByteToHexString(maxBufferSize); - qCDebug(dcZigbee()) << " Bit field:" << ZigbeeUtils::convertUint16ToHexString(bitField); - -} - -void ZigbeeNetworkManager::onRequestSimpleNodeDescriptionFinished() -{ - ZigbeeInterfaceReply *reply = static_cast(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(reply->additionalMessage().data().at(0)); - quint8 status = static_cast(reply->additionalMessage().data().at(1)); - - quint16 nwkAddress = reply->additionalMessage().data().at(2); - nwkAddress <<= 8; - nwkAddress |= reply->additionalMessage().data().at(3); - - quint8 length = static_cast(reply->additionalMessage().data().at(4)); - quint8 endPoint = static_cast(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(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:" << static_cast(deviceId); - } else { - qCDebug(dcZigbee()) << " Device ID:" << static_cast(deviceId); - } - - qCDebug(dcZigbee()) << " Bit field:" << ZigbeeUtils::convertByteToHexString(bitField); - - quint8 inputClusterCount = static_cast(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(clusterId)); - } - - quint8 outputClusterCount = static_cast(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(clusterId)); - } - -} - -void ZigbeeNetworkManager::onRequestPowerDescriptorFinished() -{ - ZigbeeInterfaceReply *reply = static_cast(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(reply->additionalMessage().data().at(0)); - quint8 status = static_cast(reply->additionalMessage().data().at(1)); - - quint16 bitField = reply->additionalMessage().data().at(2); - bitField <<= 8; - bitField |= reply->additionalMessage().data().at(3); - - qCDebug(dcZigbee()) << "Node power descriptor:"; - qCDebug(dcZigbee()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber); - qCDebug(dcZigbee()) << " Status:" << ZigbeeUtils::convertByteToHexString(status); - qCDebug(dcZigbee()) << " Bitfiled:" << ZigbeeUtils::convertUint16ToHexString(bitField); - } void ZigbeeNetworkManager::onRequestMatchDescriptorFinished() { + ZigbeeInterfaceReply *reply = static_cast(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(); +} + +void ZigbeeNetworkManager::onEnableWhitelistFinished() +{ + ZigbeeInterfaceReply *reply = static_cast(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 ZigbeeNetworkManager::processLoggingMessage(const ZigbeeInterfaceMessage &message) @@ -713,9 +580,9 @@ void ZigbeeNetworkManager::processNodeClusterList(const ZigbeeInterfaceMessage & profileId <<= 8; profileId |= static_cast(message.data().at(2)); - qCDebug(dcZigbee()) << "Node cluster list received:"; - qCDebug(dcZigbee()) << " Souce endpoint:" << sourceEndpoint; - qCDebug(dcZigbee()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast(profileId)); + qCDebug(dcZigbeeController()) << "Node cluster list received:"; + qCDebug(dcZigbeeController()) << " Souce endpoint:" << sourceEndpoint; + qCDebug(dcZigbeeController()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast(profileId)); QByteArray clusterListData = message.data().right(message.data().count() - 3); @@ -725,7 +592,7 @@ void ZigbeeNetworkManager::processNodeClusterList(const ZigbeeInterfaceMessage & clusterId <<= 8; clusterId |= clusterListData .at(i+1); - qCDebug(dcZigbee()) << " Cluster ID:" << ZigbeeUtils::clusterIdToString(static_cast(clusterId)); + qCDebug(dcZigbeeController()) << " Cluster ID:" << ZigbeeUtils::clusterIdToString(static_cast(clusterId)); } } @@ -742,10 +609,10 @@ void ZigbeeNetworkManager::processNodeAttributeList(const ZigbeeInterfaceMessage clusterId |= static_cast(message.data().at(4)); - qCDebug(dcZigbee()) << "Node attribute list received:"; - qCDebug(dcZigbee()) << " Souce endpoint:" << sourceEndpoint; - qCDebug(dcZigbee()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast(profileId)); - qCDebug(dcZigbee()) << " Cluster ID:" << ZigbeeUtils::clusterIdToString(static_cast(clusterId)); + qCDebug(dcZigbeeController()) << "Node attribute list received:"; + qCDebug(dcZigbeeController()) << " Souce endpoint:" << sourceEndpoint; + qCDebug(dcZigbeeController()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast(profileId)); + qCDebug(dcZigbeeController()) << " Cluster ID:" << ZigbeeUtils::clusterIdToString(static_cast(clusterId)); QByteArray attributeListData = message.data().right(message.data().count() - 5); @@ -754,7 +621,7 @@ void ZigbeeNetworkManager::processNodeAttributeList(const ZigbeeInterfaceMessage attribute <<= 8; attribute |= attributeListData .at(i+1); - qCDebug(dcZigbee()) << " Attribute:" << ZigbeeUtils::convertUint16ToHexString(attribute); + qCDebug(dcZigbeeController()) << " Attribute:" << ZigbeeUtils::convertUint16ToHexString(attribute); } } @@ -770,16 +637,16 @@ void ZigbeeNetworkManager::processNodeCommandIdList(const ZigbeeInterfaceMessage clusterId <<= 8; clusterId |= static_cast(message.data().at(4)); - qCDebug(dcZigbee()) << "Node command list received:"; - qCDebug(dcZigbee()) << " Souce endpoint:" << sourceEndpoint; - qCDebug(dcZigbee()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast(profileId)); - qCDebug(dcZigbee()) << " Cluster ID:" << ZigbeeUtils::clusterIdToString(static_cast(clusterId)); + qCDebug(dcZigbeeController()) << "Node command list received:"; + qCDebug(dcZigbeeController()) << " Souce endpoint:" << sourceEndpoint; + qCDebug(dcZigbeeController()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast(profileId)); + qCDebug(dcZigbeeController()) << " Cluster ID:" << ZigbeeUtils::clusterIdToString(static_cast(clusterId)); QByteArray commandListData = message.data().right(message.data().count() - 5); for (int i = 0; i < commandListData.count(); i++) { quint8 attribute = commandListData.at(i); - qCDebug(dcZigbee()) << " Command:" << ZigbeeUtils::convertByteToHexString(attribute); + qCDebug(dcZigbeeController()) << " Command:" << ZigbeeUtils::convertByteToHexString(attribute); } } @@ -809,14 +676,86 @@ void ZigbeeNetworkManager::processDeviceAnnounce(const ZigbeeInterfaceMessage &m qCDebug(dcZigbee()) << "Device announced:"; qCDebug(dcZigbee()) << " Address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress); - qCDebug(dcZigbee()) << " Extended address:" << ZigbeeUtils::convertUint64ToHexString(ieeeAddress) << ZigbeeAddress(ieeeAddress); + qCDebug(dcZigbee()) << " Extended address:" << ZigbeeAddress(ieeeAddress); qCDebug(dcZigbee()) << " Mac capabilities:" << ZigbeeUtils::convertByteToHexString(macCapability); - // TODO: parse mac capabilities + ZigbeeNode *node = new ZigbeeNode(controller(), this); + node->setShortAddress(shortAddress); + node->setExtendedAddress(ZigbeeAddress(ieeeAddress)); - requestNodeDescription(shortAddress); - requestSimpleNodeDescription(shortAddress); - requestPowerDescriptor(shortAddress); + m_nodeList.append(node); + + node->init(); + + saveNetwork(); +} + +void ZigbeeNetworkManager::processAttributeReport(const ZigbeeInterfaceMessage &message) +{ + quint8 sequenceNumber = static_cast(message.data().at(0)); + + quint16 sourceAddress = message.data().at(1); + sourceAddress <<= 8; + sourceAddress |= message.data().at(2); + + quint8 endPoint = static_cast(message.data().at(3)); + + quint16 clusterId = message.data().at(4); + clusterId <<= 8; + clusterId |= message.data().at(5); + + quint16 attributeId = message.data().at(6); + attributeId <<= 8; + attributeId |= message.data().at(7); + + quint8 attributStatus = static_cast(message.data().at(8)); + quint8 attributDataType = static_cast(message.data().at(9)); + + quint16 attributeSize = message.data().at(10); + attributeSize <<= 8; + attributeSize |= message.data().at(11); + + QByteArray data = message.data().mid(12); + Zigbee::DataType dataType = static_cast(attributDataType); + + qCDebug(dcZigbee()) << "Attribute report:"; + qCDebug(dcZigbee()) << " SQN:" << ZigbeeUtils::convertByteToHexString(sequenceNumber); + qCDebug(dcZigbee()) << " Source address:" << ZigbeeUtils::convertUint16ToHexString(sourceAddress); + qCDebug(dcZigbee()) << " End point:" << ZigbeeUtils::convertByteToHexString(endPoint); + qCDebug(dcZigbee()) << " Cluster:" << ZigbeeUtils::clusterIdToString(static_cast(clusterId)); + qCDebug(dcZigbee()) << " Attribut id:" << ZigbeeUtils::convertUint16ToHexString(attributeId); + qCDebug(dcZigbee()) << " Attribut status:" << ZigbeeUtils::convertByteToHexString(attributStatus); + qCDebug(dcZigbee()) << " Attribut data type:" << dataType; + qCDebug(dcZigbee()) << " Attribut size:" << attributeSize; + qCDebug(dcZigbee()) << " Data:" << ZigbeeUtils::convertByteArrayToHexString(data); + + switch (dataType) { + case Zigbee::CharString: + qCDebug(dcZigbee()) << " Data(converted)" << QString::fromUtf8(data); + break; + case Zigbee::Bool: + qCDebug(dcZigbee()) << " Data(converted)" << QVariant(data.toInt()).toBool(); + break; + default: + break; + } + + // TODO: find node and set attribute value + +} + +void ZigbeeNetworkManager::processLeaveIndication(const ZigbeeInterfaceMessage &message) +{ + + quint16 shortAddress = message.data().at(0); + shortAddress <<= 8; + shortAddress |= message.data().at(1); + + quint8 rejoining = message.data().at(2); + + qCDebug(dcZigbee()) << "Node leaving:" << ZigbeeUtils::convertUint16ToHexString(shortAddress) << rejoining; + + // remove node } void ZigbeeNetworkManager::onMessageReceived(const ZigbeeInterfaceMessage &message) @@ -840,6 +779,12 @@ void ZigbeeNetworkManager::onMessageReceived(const ZigbeeInterfaceMessage &messa case Zigbee::MessageTypeDeviceAnnounce: processDeviceAnnounce(message); break; + case Zigbee::MessageTypeAttributeReport: + processAttributeReport(message); + break; + case Zigbee::MessageTypeLeaveIndication: + processLeaveIndication(message); + break; default: qCDebug(dcZigbeeController()) << "Message received:" << message; break; diff --git a/zigbeenetworkmanager.h b/zigbeenetworkmanager.h index 46addaa..3388c04 100644 --- a/zigbeenetworkmanager.h +++ b/zigbeenetworkmanager.h @@ -11,21 +11,21 @@ class ZigbeeNetworkManager : public ZigbeeNode { Q_OBJECT public: - explicit ZigbeeNetworkManager(const QString &serialPort = "/dev/ttyS0", QObject *parent = nullptr); - - QString serialPort() const; - void setSerialPort(const QString &serialPort); + explicit ZigbeeNetworkManager(const int &channel = 0, const QString &serialPort = "/dev/ttyS0", QObject *parent = nullptr); QString controllerVersion() const; + QList nodeList() const; + void reset(); private: ZigbeeBridgeController *m_controller = nullptr; - QString m_serialPort; QString m_controllerVersion; quint64 m_extendedPanId; + QList m_nodeList; + quint64 generateRandomPanId(); // Controller methods @@ -39,11 +39,9 @@ private: void startNetwork(); void startScan(); void permitJoining(quint16 targetAddress = 0xfffc, const quint8 advertisingIntervall = 254); - void getPermitJoiningStatus(); - void requestNodeDescription(const quint16 &shortAddress); - void requestSimpleNodeDescription(const quint16 &shortAddress, const quint8 &endpoint = 1); - void requestPowerDescriptor(const quint16 &shortAddress); + void getPermitJoiningStatus(); + void enableWhitelist(); void requestMatchDescriptor(const quint16 &shortAddress, const Zigbee::ZigbeeProfile &profile); @@ -52,6 +50,9 @@ signals: private slots: void onMessageReceived(const ZigbeeInterfaceMessage &message); + void loadNetwork(); + void saveNetwork(); + // Controller methods finished slots void onResetControllerFinished(); void onErasePersistentDataFinished(); @@ -63,13 +64,11 @@ private slots: void onStartScanFinished(); void onGetPermitJoiningStatusFinished(); void onPermitJoiningFinished(); - - void onRequestNodeDescriptionFinished(); - void onRequestSimpleNodeDescriptionFinished(); - void onRequestPowerDescriptorFinished(); + void onEnableWhitelistFinished(); void onRequestMatchDescriptorFinished(); + // Process controller notifications/messages void processLoggingMessage(const ZigbeeInterfaceMessage &message); void processFactoryNewRestart(const ZigbeeInterfaceMessage &message); @@ -77,6 +76,8 @@ private slots: void processNodeAttributeList(const ZigbeeInterfaceMessage &message); void processNodeCommandIdList(const ZigbeeInterfaceMessage &message); void processDeviceAnnounce(const ZigbeeInterfaceMessage &message); + void processAttributeReport(const ZigbeeInterfaceMessage &message); + void processLeaveIndication(const ZigbeeInterfaceMessage &message); }; #endif // ZIGBEEMANAGER_H diff --git a/zigbeenode.cpp b/zigbeenode.cpp index fa75b5b..5a5dd95 100644 --- a/zigbeenode.cpp +++ b/zigbeenode.cpp @@ -1,16 +1,15 @@ #include "zigbeenode.h" +#include "zigbeeutils.h" +#include "loggingcategory.h" -ZigbeeNode::ZigbeeNode(QObject *parent) : QObject(parent) -{ - -} +#include quint16 ZigbeeNode::shortAddress() const { return m_shortAddress; } -quint64 ZigbeeNode::extendedAddress() const +ZigbeeAddress ZigbeeNode::extendedAddress() const { return m_extendedAddress; } @@ -20,12 +19,237 @@ ZigbeeNode::NodeType ZigbeeNode::nodeType() const return m_nodeType; } +void ZigbeeNode::init() +{ + requestNodeDescription(); + requestSimpleNodeDescription(); + requestPowerDescriptor(); +} + +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(10000); + + 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(10000); + + 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(10000); + + ZigbeeInterfaceReply *reply = controller()->sendRequest(request); + connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNode::onRequestPowerDescriptorFinished); +} + +ZigbeeNode::ZigbeeNode(ZigbeeBridgeController *controller, QObject *parent) : + QObject(parent), + m_controller(controller) +{ + +} + +ZigbeeBridgeController *ZigbeeNode::controller() +{ + return m_controller; +} + void ZigbeeNode::setShortAddress(const quint16 &shortAddress) { m_shortAddress = shortAddress; } -void ZigbeeNode::setExtendedAddress(const quint64 &extendedAddress) +void ZigbeeNode::setExtendedAddress(const ZigbeeAddress &extendedAddress) { m_extendedAddress = extendedAddress; } + +void ZigbeeNode::onRequestNodeDescriptionFinished() +{ + ZigbeeInterfaceReply *reply = static_cast(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"; + + quint8 sequenceNumber = static_cast(reply->additionalMessage().data().at(0)); + quint8 status = static_cast(reply->additionalMessage().data().at(1)); + + quint16 shortAddress = reply->additionalMessage().data().at(2); + shortAddress <<= 8; + shortAddress |= reply->additionalMessage().data().at(3); + + quint16 manufacturerCode = reply->additionalMessage().data().at(4); + 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(reply->additionalMessage().data().at(12)); + quint8 macFlags = static_cast(reply->additionalMessage().data().at(13)); + quint8 maxBufferSize = static_cast(reply->additionalMessage().data().at(14)); + + quint16 bitField = reply->additionalMessage().data().at(15); + bitField <<= 8; + bitField |= reply->additionalMessage().data().at(16); + + // TODO: find node for short address and set data + + qCDebug(dcZigbee()) << "Node descriptor:"; + 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(maximalRxSize); + qCDebug(dcZigbee()) << " Maximum Tx size:" << ZigbeeUtils::convertUint16ToHexString(maximalTxSize); + qCDebug(dcZigbee()) << " Server makk:" << ZigbeeUtils::convertUint16ToHexString(serverMask); + qCDebug(dcZigbee()) << " Descriptor flag:" << ZigbeeUtils::convertByteToHexString(descriptorFlag); + qCDebug(dcZigbee()) << " MAC flags:" << ZigbeeUtils::convertByteToHexString(macFlags); + qCDebug(dcZigbee()) << " Maximum buffer size:" << ZigbeeUtils::convertByteToHexString(maxBufferSize); + qCDebug(dcZigbee()) << " Bit field:" << ZigbeeUtils::convertUint16ToHexString(bitField); +} + +void ZigbeeNode::onRequestSimpleNodeDescriptionFinished() +{ + ZigbeeInterfaceReply *reply = static_cast(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(reply->additionalMessage().data().at(0)); + quint8 status = static_cast(reply->additionalMessage().data().at(1)); + + quint16 nwkAddress = reply->additionalMessage().data().at(2); + nwkAddress <<= 8; + nwkAddress |= reply->additionalMessage().data().at(3); + + quint8 length = static_cast(reply->additionalMessage().data().at(4)); + quint8 endPoint = static_cast(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(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(deviceId); + } else { + qCDebug(dcZigbee()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast(deviceId); + } + + qCDebug(dcZigbee()) << " Bit field:" << ZigbeeUtils::convertByteToHexString(bitField); + + quint8 inputClusterCount = static_cast(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(clusterId)); + } + + quint8 outputClusterCount = static_cast(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(clusterId)); + } + +} + +void ZigbeeNode::onRequestPowerDescriptorFinished() +{ + ZigbeeInterfaceReply *reply = static_cast(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(reply->additionalMessage().data().at(0)); + quint8 status = static_cast(reply->additionalMessage().data().at(1)); + + quint16 bitField = reply->additionalMessage().data().at(2); + bitField <<= 8; + bitField |= reply->additionalMessage().data().at(3); + + qCDebug(dcZigbee()) << "Node power descriptor:"; + qCDebug(dcZigbee()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber); + qCDebug(dcZigbee()) << " Status:" << ZigbeeUtils::convertByteToHexString(status); + qCDebug(dcZigbee()) << " Bitfiled:" << ZigbeeUtils::convertUint16ToHexString(bitField); +} diff --git a/zigbeenode.h b/zigbeenode.h index bd6b904..a09cde6 100644 --- a/zigbeenode.h +++ b/zigbeenode.h @@ -4,10 +4,17 @@ #include #include "zigbee.h" +#include "zigbeeaddress.h" +#include "zigbeebridgecontroller.h" + +class ZigbeeNetworkManager; class ZigbeeNode : public QObject { Q_OBJECT + + friend class ZigbeeNetworkManager; + public: enum NodeType { NodeTypeCoordinator = 0, @@ -23,10 +30,8 @@ public: }; Q_ENUM(FrequencyBand) - explicit ZigbeeNode(QObject *parent = nullptr); - quint16 shortAddress() const; - quint64 extendedAddress() const; + ZigbeeAddress extendedAddress() const; // Information from node descriptor NodeType nodeType() const; @@ -34,18 +39,36 @@ public: bool canBeCoordinator() const; + void init(); + private: + ZigbeeBridgeController *m_controller; + quint16 m_shortAddress = 0; - quint64 m_extendedAddress = 0; + ZigbeeAddress m_extendedAddress; NodeType m_nodeType; -protected: - void setShortAddress(const quint16 &shortAddress); - void setExtendedAddress(const quint64 &extendedAddress); + void requestNodeDescription(); + void requestSimpleNodeDescription(); + void requestPowerDescriptor(); +protected: + ZigbeeNode(ZigbeeBridgeController *controller, QObject *parent = nullptr); + + ZigbeeBridgeController *controller(); + + void setShortAddress(const quint16 &shortAddress); + void setExtendedAddress(const ZigbeeAddress &extendedAddress); + signals: +private slots: + void onRequestNodeDescriptionFinished(); + void onRequestSimpleNodeDescriptionFinished(); + void onRequestPowerDescriptorFinished(); + + public slots: };