From d64b4711d139255e4c3ee9b58d229b791401de18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 29 Oct 2020 18:13:23 +0100 Subject: [PATCH] Minor changes for the nymea integration and add network destroy --- .../deconz/zigbeebridgecontrollerdeconz.cpp | 26 ++++++------ .../backends/deconz/zigbeenetworkdeconz.cpp | 41 +++++++++++++++---- .../backends/deconz/zigbeenetworkdeconz.h | 1 + .../backends/nxp/zigbeenetworknxp.cpp | 32 +++++++++++---- .../backends/nxp/zigbeenetworknxp.h | 2 +- libnymea-zigbee/zigbeechannelmask.cpp | 4 +- libnymea-zigbee/zigbeenetwork.cpp | 32 ++------------- libnymea-zigbee/zigbeenetwork.h | 3 +- 8 files changed, 80 insertions(+), 61 deletions(-) diff --git a/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp b/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp index 70749af..3f3805d 100644 --- a/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp +++ b/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp @@ -1045,19 +1045,19 @@ QDebug operator<<(QDebug debug, const DeconzDeviceState &deviceState) QDebug operator<<(QDebug debug, const DeconzNetworkConfiguration &configuration) { - debug.nospace() << "Network configuration:" << "\n"; + debug.nospace() << "Network configuration: " << "\n"; debug.nospace() << " - Node type:" << configuration.nodeType << "\n"; - debug.nospace() << " - IEEE address:" << configuration.ieeeAddress.toString() << "\n"; - debug.nospace() << " - NWK address:" << ZigbeeUtils::convertUint16ToHexString(configuration.shortAddress) << "\n"; - debug.nospace() << " - PAN ID:" << ZigbeeUtils::convertUint16ToHexString(configuration.panId) << "\n"; - debug.nospace() << " - Extended PAN ID:" << ZigbeeUtils::convertUint64ToHexString(configuration.extendedPanId) << "\n"; - debug.nospace() << " - APS Extended PAN ID:" << ZigbeeUtils::convertUint64ToHexString(configuration.apsExtendedPanId) << "\n"; - debug.nospace() << " - Trust center IEEE address:" << configuration.trustCenterAddress.toString() << "\n"; - debug.nospace() << " - Channel mask:" << ZigbeeChannelMask(configuration.channelMask) << "\n"; - debug.nospace() << " - Channel:" << configuration.currentChannel << "\n"; - debug.nospace() << " - Security mode:" << configuration.securityMode << "\n"; - debug.nospace() << " - Protocol version:" << ZigbeeUtils::convertUint16ToHexString(configuration.protocolVersion) << "\n"; - debug.nospace() << " - Network update ID:" << ZigbeeUtils::convertByteToHexString(configuration.networkUpdateId) << "\n"; - debug.nospace() << " - Watchdog TTL:" << configuration.watchdogTimeout << "\n"; + debug.nospace() << " - IEEE address: " << configuration.ieeeAddress.toString() << "\n"; + debug.nospace() << " - NWK address: " << ZigbeeUtils::convertUint16ToHexString(configuration.shortAddress) << "\n"; + debug.nospace() << " - PAN ID: " << ZigbeeUtils::convertUint16ToHexString(configuration.panId) << "\n"; + debug.nospace() << " - Extended PAN ID: " << ZigbeeUtils::convertUint64ToHexString(configuration.extendedPanId) << "\n"; + debug.nospace() << " - APS Extended PAN ID: " << ZigbeeUtils::convertUint64ToHexString(configuration.apsExtendedPanId) << "\n"; + debug.nospace() << " - Trust center IEEE address: " << configuration.trustCenterAddress.toString() << "\n"; + debug.nospace() << " - Channel mask: " << ZigbeeChannelMask(configuration.channelMask) << "\n"; + debug.nospace() << " - Channel: " << configuration.currentChannel << "\n"; + debug.nospace() << " - Security mode: " << configuration.securityMode << "\n"; + debug.nospace() << " - Protocol version: " << ZigbeeUtils::convertUint16ToHexString(configuration.protocolVersion) << "\n"; + debug.nospace() << " - Network update ID: " << ZigbeeUtils::convertByteToHexString(configuration.networkUpdateId) << "\n"; + debug.nospace() << " - Watchdog TTL: " << configuration.watchdogTimeout << "\n"; return debug.space(); } diff --git a/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.cpp b/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.cpp index 18d7475..a8cfd4c 100644 --- a/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.cpp +++ b/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.cpp @@ -291,6 +291,15 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo } case CreateNetworkStateInitializeCoordinatorNode: { if (m_coordinatorNode) { + if (!macAddress().isNull() && m_coordinatorNode->extendedAddress() != macAddress()) { + qCWarning(dcZigbeeNetwork()) << "The mac address of the coordinator has changed since the network has been set up."; + qCWarning(dcZigbeeNetwork()) << "The network is bound to a specific controller. Since the controller has changed the network can not be started."; + qCWarning(dcZigbeeNetwork()) << "Please factory reset the network or plug in the original controller."; + setError(ZigbeeNetwork::ErrorHardwareModuleChanged); + stopNetwork(); + return; + } + qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done."; m_database->saveNode(m_coordinatorNode); m_initializing = false; @@ -384,8 +393,10 @@ void ZigbeeNetworkDeconz::setPermitJoiningInternal(bool permitJoining) connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, permitJoining, duration](){ if (reply->zigbeeApsStatus() != Zigbee::ZigbeeApsStatusSuccess) { qCDebug(dcZigbeeNetwork()) << "Could not set permit join to" << duration; - m_permitJoining = false; - emit permitJoiningChanged(m_permitJoining); + if (m_permitJoining != false) { + m_permitJoining = false; + emit permitJoiningChanged(m_permitJoining); + } return; } qCDebug(dcZigbeeNetwork()) << "Permit join request finished successfully"; @@ -543,13 +554,17 @@ void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available) qCWarning(dcZigbeeNetwork()) << "Hardware controller is not available any more."; setError(ErrorHardwareUnavailable); m_initializing = false; - m_permitJoining = false; - emit permitJoiningChanged(m_permitJoining); + if (m_permitJoining != false) { + m_permitJoining = false; + emit permitJoiningChanged(m_permitJoining); + } setState(StateOffline); } else { m_error = ErrorNoError; - m_permitJoining = false; - m_initializing = true; + if (m_permitJoining != false) { + m_permitJoining = false; + emit permitJoiningChanged(m_permitJoining); + } emit permitJoiningChanged(m_permitJoining); setState(StateStarting); qCDebug(dcZigbeeNetwork()) << "Hardware controller is now available."; @@ -689,8 +704,10 @@ void ZigbeeNetworkDeconz::startNetwork() return; } - m_permitJoining = false; - emit permitJoiningChanged(m_permitJoining); + if (m_permitJoining != false) { + m_permitJoining = false; + emit permitJoiningChanged(m_permitJoining); + } // Note: wait for the controller available signal and start the initialization there @@ -710,6 +727,7 @@ void ZigbeeNetworkDeconz::stopNetwork() qCDebug(dcZigbeeNetwork()) << "Network left successfully. SQN:" << reply->sequenceNumber(); setState(StateOffline); + m_controller->disable(); }); } @@ -727,3 +745,10 @@ void ZigbeeNetworkDeconz::factoryResetNetwork() qCDebug(dcZigbeeNetwork()) << "The factory reset is finished. Start restart with a fresh network."; startNetwork(); } + +void ZigbeeNetworkDeconz::destroyNetwork() +{ + qCDebug(dcZigbeeNetwork()) << "Destroy network and delete the database"; + m_controller->disable(); + clearSettings(); +} diff --git a/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.h b/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.h index 3e6d0e3..bbdd5a2 100644 --- a/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.h +++ b/libnymea-zigbee/backends/deconz/zigbeenetworkdeconz.h @@ -98,6 +98,7 @@ public slots: void stopNetwork() override; void reset() override; void factoryResetNetwork() override; + void destroyNetwork() override; }; diff --git a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp index e8acec5..4589ef0 100644 --- a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp +++ b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp @@ -313,6 +313,15 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr // Initialize the coordinator node if not already done. if (m_coordinatorNode) { + if (!macAddress().isNull() && ZigbeeAddress(ieeeAddress) != macAddress()) { + qCWarning(dcZigbeeNetwork()) << "The mac address of the coordinator has changed since the network has been set up."; + qCWarning(dcZigbeeNetwork()) << "The network is bound to a specific controller. Since the controller has changed the network can not be started."; + qCWarning(dcZigbeeNetwork()) << "Please factory reset the network or plug in the original controller."; + setError(ZigbeeNetwork::ErrorHardwareModuleChanged); + stopNetwork(); + return; + } + qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done."; m_database->saveNode(m_coordinatorNode); setState(StateRunning); @@ -500,8 +509,10 @@ void ZigbeeNetworkNxp::setPermitJoiningInternal(bool permitJoining) connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, permitJoining, duration](){ if (reply->zigbeeApsStatus() != Zigbee::ZigbeeApsStatusSuccess) { qCDebug(dcZigbeeNetwork()) << "Could not set permit join to" << duration; - m_permitJoining = false; - emit permitJoiningChanged(m_permitJoining); + if (m_permitJoining != false) { + m_permitJoining = false; + emit permitJoiningChanged(m_permitJoining); + } return; } @@ -533,12 +544,12 @@ void ZigbeeNetworkNxp::startNetwork() { loadNetwork(); - m_permitJoining = false; - emit permitJoiningChanged(m_permitJoining); - - if (!m_controller->enable(serialPortName(), serialBaudrate())) { + if (m_permitJoining != false) { m_permitJoining = false; emit permitJoiningChanged(m_permitJoining); + } + + if (!m_controller->enable(serialPortName(), serialBaudrate())) { setState(StateOffline); setError(ErrorHardwareUnavailable); return; @@ -549,7 +560,7 @@ void ZigbeeNetworkNxp::startNetwork() void ZigbeeNetworkNxp::stopNetwork() { - + m_controller->disable(); } void ZigbeeNetworkNxp::reset() @@ -571,3 +582,10 @@ void ZigbeeNetworkNxp::factoryResetNetwork() qCDebug(dcZigbeeNetwork()) << "Factory reset reply finished" << reply->status(); }); } + +void ZigbeeNetworkNxp::destroyNetwork() +{ + qCDebug(dcZigbeeNetwork()) << "Destroy network and delete the database"; + m_controller->disable(); + clearSettings(); +} diff --git a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h index 8989b20..bac935e 100644 --- a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h +++ b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h @@ -47,7 +47,6 @@ public: ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override; ZigbeeNetworkReply *setPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe); - private: ZigbeeBridgeControllerNxp *m_controller = nullptr; bool m_networkRunning = false; @@ -84,6 +83,7 @@ public slots: void stopNetwork() override; void reset() override; void factoryResetNetwork() override; + void destroyNetwork() override; }; #endif // ZIGBEENETWORKNXP_H diff --git a/libnymea-zigbee/zigbeechannelmask.cpp b/libnymea-zigbee/zigbeechannelmask.cpp index 84d1094..156b3a6 100644 --- a/libnymea-zigbee/zigbeechannelmask.cpp +++ b/libnymea-zigbee/zigbeechannelmask.cpp @@ -150,6 +150,6 @@ QDebug operator<<(QDebug debug, const ZigbeeChannelMask &channelMaks) { debug.nospace() << "ChannelMask(" << ZigbeeUtils::convertUint32ToHexString(channelMaks.toUInt32()); debug.nospace() << ", " << channelMaks.channelArray(); - debug.nospace() << ")"; - return debug.space(); + debug.nospace() << ") "; + return debug; } diff --git a/libnymea-zigbee/zigbeenetwork.cpp b/libnymea-zigbee/zigbeenetwork.cpp index 3dc76d4..fbc1282 100644 --- a/libnymea-zigbee/zigbeenetwork.cpp +++ b/libnymea-zigbee/zigbeenetwork.cpp @@ -282,6 +282,8 @@ void ZigbeeNetwork::addNodeInternally(ZigbeeNode *node) // Set the coordinator node if the short address is 0x0000 if (node->shortAddress() == 0) { m_coordinatorNode = node; + m_macAddress = m_coordinatorNode->extendedAddress(); + emit macAddressChanged(m_macAddress); } // FIXME: check when and how the note will be reachable @@ -332,42 +334,15 @@ ZigbeeNode *ZigbeeNetwork::createNode(quint16 shortAddress, const ZigbeeAddress return node; } -void ZigbeeNetwork::saveNetwork() -{ -// qCDebug(dcZigbeeNetwork()) << "Save current network configuration to" << m_settingsFileName; -// QSettings settings(m_settingsFileName, QSettings::IniFormat, this); -// settings.beginGroup("ZigbeeNetwork"); -// settings.setValue("panId", panId()); -// settings.setValue("channel", channel()); -// settings.setValue("networkKey", securityConfiguration().networkKey().toString()); -// settings.setValue("trustCenterLinkKey", securityConfiguration().globalTrustCenterLinkKey().toString()); -// settings.endGroup(); -} - void ZigbeeNetwork::loadNetwork() { qCDebug(dcZigbeeNetwork()) << "Loading network from settings directory" << m_settingsDirectory.absolutePath(); if (!m_database) { - QString networkDatabaseFileName = m_settingsDirectory.absolutePath() + QDir::separator() + QString("zigbee-network-%1.db").arg(m_networkUuid.toString()); + QString networkDatabaseFileName = m_settingsDirectory.absolutePath() + QDir::separator() + QString("zigbee-network-%1.db").arg(m_networkUuid.toString().remove('{').remove('}')); qCDebug(dcZigbeeNetwork()) << "Using ZigBee network database" << QFileInfo(networkDatabaseFileName).fileName(); m_database = new ZigbeeNetworkDatabase(this, networkDatabaseFileName, this); } -// QSettings settings(m_settingsFileName, QSettings::IniFormat, this); -// settings.beginGroup("ZigbeeNetwork"); -// quint16 panId = static_cast(settings.value("panId", 0).toUInt()); -// setPanId(panId); -// setChannel(settings.value("channel", 0).toUInt()); -// ZigbeeNetworkKey netKey(settings.value("networkKey", QString()).toString()); -// if (netKey.isValid()) -// m_securityConfiguration.setNetworkKey(netKey); - -// ZigbeeNetworkKey tcKey(settings.value("trustCenterLinkKey", QString("5A6967426565416C6C69616E63653039")).toString()); -// if (!tcKey.isValid()) -// m_securityConfiguration.setGlobalTrustCenterlinkKey(tcKey); - -// settings.endGroup(); // Network - QList nodes = m_database->loadNodes(); foreach (ZigbeeNode *node, nodes) { node->setState(ZigbeeNode::StateInitialized); @@ -469,7 +444,6 @@ void ZigbeeNetwork::setState(ZigbeeNetwork::State state) m_state = state; if (state == StateRunning) { - saveNetwork(); qCDebug(dcZigbeeNetwork()) << this; } emit stateChanged(m_state); diff --git a/libnymea-zigbee/zigbeenetwork.h b/libnymea-zigbee/zigbeenetwork.h index ca71ef2..0158c69 100644 --- a/libnymea-zigbee/zigbeenetwork.h +++ b/libnymea-zigbee/zigbeenetwork.h @@ -60,6 +60,7 @@ public: enum Error { ErrorNoError, ErrorHardwareUnavailable, + ErrorHardwareModuleChanged, ErrorZigbeeError }; Q_ENUM(Error) @@ -163,7 +164,6 @@ protected: ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, quint8 macCapabilities, QObject *parent); virtual void setPermitJoiningInternal(bool permitJoining) = 0; - void saveNetwork(); void loadNetwork(); void clearSettings(); @@ -215,6 +215,7 @@ public slots: virtual void stopNetwork() = 0; virtual void reset() = 0; virtual void factoryResetNetwork() = 0; + virtual void destroyNetwork() = 0; };