From 7c7ba4f13ae2fb7ad12c5dc34e333585ea00e791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 28 Feb 2020 11:41:03 +0100 Subject: [PATCH] Restored basic network starting and resetting --- libnymea-zigbee/libnymea-zigbee.pro | 2 + libnymea-zigbee/nxp/zigbeenetworknxp.cpp | 318 ++++++++++++----------- libnymea-zigbee/nxp/zigbeenetworknxp.h | 12 +- libnymea-zigbee/nxp/zigbeenodenxp.cpp | 6 + libnymea-zigbee/nxp/zigbeenodenxp.h | 17 ++ libnymea-zigbee/zigbeenetwork.cpp | 28 +- libnymea-zigbee/zigbeenetwork.h | 11 +- libnymea-zigbee/zigbeenetworkmanager.cpp | 16 +- libnymea-zigbee/zigbeenetworkmanager.h | 11 +- libnymea-zigbee/zigbeeutils.cpp | 1 - nymea-zigbee.pro | 1 - 11 files changed, 230 insertions(+), 193 deletions(-) create mode 100644 libnymea-zigbee/nxp/zigbeenodenxp.cpp create mode 100644 libnymea-zigbee/nxp/zigbeenodenxp.h diff --git a/libnymea-zigbee/libnymea-zigbee.pro b/libnymea-zigbee/libnymea-zigbee.pro index 0472cbe..d399582 100644 --- a/libnymea-zigbee/libnymea-zigbee.pro +++ b/libnymea-zigbee/libnymea-zigbee.pro @@ -10,6 +10,7 @@ SOURCES += \ nxp/interface/zigbeeinterfacereply.cpp \ nxp/zigbeenetworknxp.cpp \ nxp/zigbeebridgecontrollernxp.cpp \ + nxp/zigbeenodenxp.cpp \ zigbeecluster.cpp \ zigbeeclusterattribute.cpp \ zigbeenetwork.cpp \ @@ -29,6 +30,7 @@ HEADERS += \ nxp/interface/zigbeeinterfacereply.h \ nxp/zigbeenetworknxp.h \ nxp/zigbeebridgecontrollernxp.h \ + nxp/zigbeenodenxp.h \ zigbeecluster.h \ zigbeeclusterattribute.h \ zigbeenetwork.h \ diff --git a/libnymea-zigbee/nxp/zigbeenetworknxp.cpp b/libnymea-zigbee/nxp/zigbeenetworknxp.cpp index 53f4186..fcdc77b 100644 --- a/libnymea-zigbee/nxp/zigbeenetworknxp.cpp +++ b/libnymea-zigbee/nxp/zigbeenetworknxp.cpp @@ -24,7 +24,19 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state) m_networkRunning = false; qCDebug(dcZigbeeNetwork()) << "Starting state changed: Erase persistant data"; ZigbeeInterfaceReply *reply = m_controller->commandErasePersistantData(); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandErasePersistentDataFinished); + connect(reply, &ZigbeeInterfaceReply::finished, this, [this, reply](){ + reply->deleteLater(); + + if (reply->status() != ZigbeeInterfaceReply::Success) { + qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage(); + // TODO: check error handling + return; + } + + m_factoryResetting = false; + qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; + setStartingState(StartingStateReset); + }); break; } case StartingStateReset: { @@ -38,7 +50,18 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state) // }); qCDebug(dcZigbeeNetwork()) << "Starting state changed: Reset controller"; ZigbeeInterfaceReply *reply = m_controller->commandResetController(); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandResetControllerFinished); + connect(reply, &ZigbeeInterfaceReply::finished, this, [reply](){ + 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"; + // Note: the controller is now sending a log of cluster and attribte/command information + // After the reset the state machine will continue + }); break; } case StartingStateGetVersion: { @@ -52,7 +75,17 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state) setExtendedPanId(ZigbeeUtils::generateRandomPanId()); } ZigbeeInterfaceReply *reply = m_controller->commandSetExtendedPanId(extendedPanId()); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandSetExtendedPanIdFinished); + connect(reply, &ZigbeeInterfaceReply::finished, this, [this, reply](){ + 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"; + setStartingState(StartingStateSetChannel); + }); break; } case StartingStateSetChannel: { @@ -74,19 +107,49 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state) qCDebug(dcZigbeeNetwork()) << "Using channel" << channel() << "for the zigbee network."; reply = m_controller->commandSetChannelMask(channelMask); } - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandSetChannelMaskFinished); + connect(reply, &ZigbeeInterfaceReply::finished, this, [this, reply](){ + reply->deleteLater(); + + if (reply->status() != ZigbeeInterfaceReply::Success) { + qCWarning(dcZigbeeNetwork()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage(); + return; + } + + qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; + setStartingState(StartingStateSetSecurity); + }); break; } case StartingStateSetSecurity: { qCDebug(dcZigbeeNetwork()) << "Starting state changed: Set security configuration"; ZigbeeInterfaceReply *reply = m_controller->commandSetSecurityStateAndKey(4, 0, 1, "5A6967426565416C6C69616E63653039"); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandSetSecurityFinished); + connect(reply, &ZigbeeInterfaceReply::finished, this, [this, reply](){ + 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"; + setStartingState(StartingStateSetNodeType); + }); break; } case StartingStateSetNodeType: { qCDebug(dcZigbeeNetwork()) << "Starting state changed: Set node type"; ZigbeeInterfaceReply *reply = m_controller->commandSetNodeType(ZigbeeNode::NodeTypeCoordinator); - connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandSetNodeTypeFinished); + connect(reply, &ZigbeeInterfaceReply::finished, this, [this, reply](){ + 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"; + setStartingState(StartingStateStartNetwork); + }); break; } case StartingStateStartNetwork: { @@ -95,11 +158,6 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state) connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandStartNetworkFinished); break; } - case StartingStateGetPermitJoinStatus: { - qCDebug(dcZigbeeNetwork()) << "Starting state changed: Get permit join status"; - readPermitJoinStatus(); - break; - } case StartingStateReadeNodeDescriptor: { qCDebug(dcZigbeeNetwork()) << "Starting state changed: Read coordinator node descriptor"; //ZigbeeInterfaceReply *reply = m_controller->commandNodeDescriptorRequest(0x0000); @@ -140,7 +198,8 @@ void ZigbeeNetworkNxp::readControllerVersion() //m_controllerFirmwareVersion = QString("%1.%2").arg(majorVersion).arg(minorVersion); qCDebug(dcZigbeeNetwork()) << "Controller version:" << QString("%1.%2").arg(majorVersion).arg(minorVersion); - if (m_startingState == StartingStateGetVersion) setStartingState(StartingStateSetPanId); + if (m_startingState == StartingStateGetVersion) + setStartingState(StartingStateSetPanId); }); } @@ -159,7 +218,6 @@ void ZigbeeNetworkNxp::readPermitJoinStatus() qCDebug(dcZigbeeController()) << reply->additionalMessage(); setPermitJoining(static_cast(reply->additionalMessage().data().at(0))); - if (m_startingState == StartingStateGetPermitJoinStatus) setStartingState(StartingStateReadeNodeDescriptor); }); } @@ -327,7 +385,9 @@ void ZigbeeNetworkNxp::processFactoryNewRestart(const ZigbeeInterfaceMessage &me } qCDebug(dcZigbeeNetwork()) << "Restart finished. Current controller state:" << controllerStatusString; - if (m_startingState == StartingStateReset) setStartingState(StartingStateGetVersion); + + if (m_startingState == StartingStateReset) + setStartingState(StartingStateGetVersion); } void ZigbeeNetworkNxp::processNodeClusterList(const ZigbeeInterfaceMessage &message) @@ -463,7 +523,7 @@ void ZigbeeNetworkNxp::processAttributeReport(const ZigbeeInterfaceMessage &mess QByteArray attributeData = data.right(dataSize); if (attributeData.length() != dataSize) { - qCCritical(dcZigbeeNetwork()) << "HACK" << attributeData.length() << "!=" << dataSize; + qCWarning(dcZigbeeNetwork()) << "HACK" << attributeData.length() << "!=" << dataSize; // Note: the NXP firmware for JN5169 has a bug here and does not send the attributeStatus. // Repars data without attribute status sequenceNumber = 0; @@ -504,13 +564,13 @@ void ZigbeeNetworkNxp::processAttributeReport(const ZigbeeInterfaceMessage &mess } // FIXME -// ZigbeeNode *node = getZigbeeNode(sourceAddress); -// if (!node) { -// qCWarning(dcZigbeeNode()) << "Received an attribute report from an unknown node. Ignoring data."; -// return; -// } + // ZigbeeNode *node = getZigbeeNode(sourceAddress); + // if (!node) { + // qCWarning(dcZigbeeNode()) << "Received an attribute report from an unknown node. Ignoring data."; + // return; + // } -// node->setClusterAttribute(static_cast(clusterId), ZigbeeClusterAttribute(attributeId, dataType, attributeData)); + // node->setClusterAttribute(static_cast(clusterId), ZigbeeClusterAttribute(attributeId, dataType, attributeData)); } void ZigbeeNetworkNxp::processLeaveIndication(const ZigbeeInterfaceMessage &message) @@ -566,7 +626,8 @@ void ZigbeeNetworkNxp::processRestartProvisioned(const ZigbeeInterfaceMessage &m if (m_startingState == StartingStateReset) { if (m_networkRunning) { qCDebug(dcZigbeeNetwork()) << "Reset finished. Network already running. No need to set it up"; - setStartingState(StartingStateGetPermitJoinStatus); + // FIXME: get network status + //setStartingState(StartingStateGetPermitJoinStatus); } else { qCDebug(dcZigbeeNetwork()) << "Reset finished. Set up network"; setStartingState(StartingStateGetVersion); @@ -637,16 +698,16 @@ void ZigbeeNetworkNxp::onControllerAvailableChanged(bool available) if (!available) { // FIXME -// foreach (ZigbeeNode *node, nodes()) { -// node->setConnected(false); -// } + // foreach (ZigbeeNode *node, nodes()) { + // node->setConnected(false); + // } setError(ErrorHardwareUnavailable); setPermitJoining(false); setState(StateOffline); setStartingState(StartingStateNone); } else { - setError(ErrorNoError); + m_error = ErrorNoError; setState(StateStarting); setStartingState(StartingStateReset); } @@ -704,66 +765,6 @@ void ZigbeeNetworkNxp::onCommandSoftResetControllerFinished() qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; } -void ZigbeeNetworkNxp::onCommandErasePersistentDataFinished() -{ - ZigbeeInterfaceReply *reply = static_cast(sender()); - reply->deleteLater(); - - if (reply->status() != ZigbeeInterfaceReply::Success) { - qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage(); - return; - } - - m_factoryResetting = false; - - qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; - if (m_startingState == StartingStateErase) { - setStartingState(StartingStateReset); - } -} - -void ZigbeeNetworkNxp::onCommandSetExtendedPanIdFinished() -{ - 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"; - if (m_startingState == StartingStateSetPanId) setStartingState(StartingStateSetChannel); -} - -void ZigbeeNetworkNxp::onCommandSetChannelMaskFinished() -{ - ZigbeeInterfaceReply *reply = static_cast(sender()); - reply->deleteLater(); - - if (reply->status() != ZigbeeInterfaceReply::Success) { - qCWarning(dcZigbeeNetwork()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage(); - return; - } - - qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; - if (m_startingState == StartingStateSetChannel) setStartingState(StartingStateSetSecurity); -} - -void ZigbeeNetworkNxp::onCommandSetNodeTypeFinished() -{ - 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"; - if (m_startingState == StartingStateSetNodeType) setStartingState(StartingStateStartNetwork); -} - void ZigbeeNetworkNxp::onCommandStartNetworkFinished() { ZigbeeInterfaceReply *reply = static_cast(sender()); @@ -777,7 +778,8 @@ void ZigbeeNetworkNxp::onCommandStartNetworkFinished() qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; qCDebug(dcZigbeeController()) << reply->additionalMessage(); processNetworkFormed(reply->additionalMessage()); - if (m_startingState == StartingStateStartNetwork) setStartingState(StartingStateGetPermitJoinStatus); + // FIXME: start creating coordinator node + //if (m_startingState == StartingStateStartNetwork) setStartingState(StartingStateGetPermitJoinStatus); } void ZigbeeNetworkNxp::onCommandStartScanFinished() @@ -809,80 +811,70 @@ void ZigbeeNetworkNxp::onCommandRequestMatchDescriptorFinished() qCDebug(dcZigbeeController()) << reply->additionalMessage(); } -void ZigbeeNetworkNxp::onCommandSetSecurityFinished() -{ - 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"; - if (m_startingState == StartingStateSetSecurity) setStartingState(StartingStateSetNodeType); -} - void ZigbeeNetworkNxp::processNetworkFormed(const ZigbeeInterfaceMessage &message) { // Parse network status - QByteArray data = message.data(); - quint8 networkStatus = static_cast(data.at(0)); - QString networkStatusString; + QByteArray data = message.data(); - bool success = false; + quint8 networkStatus = 0; + quint16 shortAddress = 0; + quint64 extendedAddress = 0; + quint8 currentChannel = 0; - if (networkStatus == 0) { - networkStatusString = "joined"; - success = true; - } else if (networkStatus == 1) { - networkStatusString = "created"; - success = true; - } else if (networkStatus >= 128 && networkStatus <= 244) { - networkStatusString = "failed: Zigbee event code: " + QString::number(networkStatus); - } else { - networkStatusString = "unknown"; - } + QDataStream stream(&data, QIODevice::ReadOnly); + stream >> networkStatus >> shortAddress >> extendedAddress >> currentChannel; - if (!success) { - qCWarning(dcZigbeeNetwork()) << "Forming network failed" << networkStatusString; - setPermitJoining(false); - setStartingState(StartingStateNone); - setState(StateOffline); - setError(ErrorZigbeeError); - m_networkRunning = false; - return; - } + QString networkStatusString; + if (networkStatus == 0) { + networkStatusString = "joined"; + } else if (networkStatus == 1) { + networkStatusString = "formed"; + } else if (networkStatus >= 128 && networkStatus <= 244) { + networkStatusString = "failed: Zigbee event code: " + QString::number(networkStatus); + } else { + networkStatusString = "unknown"; + } - quint16 shortAddress = ZigbeeUtils::convertByteArrayToUint16(data.mid(1, 2)); - quint64 extendedAddress = ZigbeeUtils::convertByteArrayToUint64(data.mid(3, 8)); + if (networkStatus != Zigbee::ZigbeeNwkLayerStatusJointNetwork && networkStatus != Zigbee::ZigbeeNwkLayerStatusFormedNetwork) { + qCWarning(dcZigbeeNetwork()) << "Forming network failed" << networkStatusString; + setPermitJoining(false); + setStartingState(StartingStateNone); + setState(StateOffline); + setError(ErrorZigbeeError); + m_networkRunning = false; + return; + } - // Parse network channel - quint8 channel = static_cast(data.at(11)); + setChannel(currentChannel); - qCDebug(dcZigbeeNetwork()).noquote() << "Network" << networkStatusString; - qCDebug(dcZigbeeNetwork()) << " Extended PAN ID:" << extendedPanId(); - qCDebug(dcZigbeeNetwork()) << " Address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress); - qCDebug(dcZigbeeNetwork()) << " Extended address:" << ZigbeeAddress(extendedAddress); - qCDebug(dcZigbeeNetwork()) << " Channel:" << channel; - qCDebug(dcZigbeeNetwork()) << " Permit joining:" << permitJoining(); + // Parse network channel + qCDebug(dcZigbeeNetwork()).noquote() << "Network" << networkStatusString; + qCDebug(dcZigbeeNetwork()) << " Extended PAN ID:" << extendedPanId(); + qCDebug(dcZigbeeNetwork()) << " Address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress); + qCDebug(dcZigbeeNetwork()) << " Extended address:" << ZigbeeAddress(extendedAddress); + qCDebug(dcZigbeeNetwork()) << " Channel:" << channel(); + qCDebug(dcZigbeeNetwork()) << " Permit joining:" << permitJoining(); - m_networkRunning = true; + saveNetwork(); - // FIXME: create coordinator node + m_networkRunning = true; + setState(StateRunning); -// // Set the node information -// setShortAddress(shortAddress); -// setExtendedAddress(ZigbeeAddress(extendedAddress)); -// setChannel(channel); + // FIXME: create coordinator node -// if (!hasNode(this->shortAddress())) -// addUnitializedNode(this); + // // Set the node information + // setShortAddress(shortAddress); + // setExtendedAddress(ZigbeeAddress(extendedAddress)); + // setChannel(channel); + + // if (!hasNode(this->shortAddress())) + // addUnitializedNode(this); } void ZigbeeNetworkNxp::startNetwork() { + // FIXME: define if router or coordinator qCDebug(dcZigbeeNetwork()) << "Start network..."; if (m_controller) { qCDebug(dcZigbeeNetwork()) << "Clean up old controller..."; @@ -890,7 +882,7 @@ void ZigbeeNetworkNxp::startNetwork() m_controller = nullptr; } - qCDebug(dcZigbeeNetwork()) << "Create new controller..."; + qCDebug(dcZigbeeNetwork()) << "Create new controller..." << state(); m_controller = new ZigbeeBridgeControllerNxp(this); connect(m_controller, &ZigbeeBridgeControllerNxp::messageReceived, this, &ZigbeeNetworkNxp::onMessageReceived); connect(m_controller, &ZigbeeBridgeControllerNxp::availableChanged, this, &ZigbeeNetworkNxp::onControllerAvailableChanged); @@ -898,16 +890,39 @@ void ZigbeeNetworkNxp::startNetwork() if (state() == StateUninitialized) loadNetwork(); + if (extendedPanId() == 0 && channel() == 0) { + m_factoryResetting = true; + } + + setState(StateOffline); + + // Check if we have to create a pan ID and select the channel + if (extendedPanId() == 0) { + setExtendedPanId(ZigbeeUtils::generateRandomPanId()); + qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId(); + } + + // TODO: get desired channel, by default use all + + if (!m_controller->enable(serialPortName(), serialBaudrate())) { setPermitJoining(false); setState(StateOffline); setStartingState(StartingStateNone); setError(ErrorHardwareUnavailable); - } else { - // Reset - setStartingState(StartingStateReset); - setState(StateStarting); + return; } + + setPermitJoining(false); + + // Note: if we are factory resetting, erase also the data on the controller + if (m_factoryResetting) { + setStartingState(StartingStateReset); + } else { + setStartingState(StartingStateErase); + } + + setState(StateStarting); } void ZigbeeNetworkNxp::stopNetwork() @@ -928,9 +943,10 @@ void ZigbeeNetworkNxp::stopNetwork() void ZigbeeNetworkNxp::factoryResetNetwork() { qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone."; + m_factoryResetting = true; clearSettings(); - - setState(StateStarting); - setStartingState(StartingStateErase); + setState(StateUninitialized); + qCDebug(dcZigbeeNetwork()) << "The factory reset is finished. Start restart with a fresh network."; + startNetwork(); } diff --git a/libnymea-zigbee/nxp/zigbeenetworknxp.h b/libnymea-zigbee/nxp/zigbeenetworknxp.h index 740e18f..64bdc84 100644 --- a/libnymea-zigbee/nxp/zigbeenetworknxp.h +++ b/libnymea-zigbee/nxp/zigbeenetworknxp.h @@ -22,7 +22,6 @@ private: StartingStateSetSecurity, StartingStateSetNodeType, StartingStateStartNetwork, - StartingStateGetPermitJoinStatus, StartingStateReadeNodeDescriptor, StartingStateReadPowerDescriptor }; @@ -43,13 +42,9 @@ private slots: // Controller command finished slots void onCommandResetControllerFinished(); void onCommandSoftResetControllerFinished(); - void onCommandErasePersistentDataFinished(); - void onCommandSetExtendedPanIdFinished(); - void onCommandSetChannelMaskFinished(); - void onCommandSetNodeTypeFinished(); void onCommandStartNetworkFinished(); void onCommandStartScanFinished(); - void onCommandEnableWhitelistFinished(); + //void onCommandEnableWhitelistFinished(); // void onCommandNodeDescriptorRequestFinished(); // void onCommandSimpleDescriptorRequestFinished(); @@ -60,9 +55,8 @@ private slots: void onCommandRequestLinkQualityFinished(); void onCommandRequestMatchDescriptorFinished(); - void onCommandSetSecurityFinished(); - void onCommandNetworkAddressRequestFinished(); - void onCommandAuthenticateDeviceFinished(); +// void onCommandNetworkAddressRequestFinished(); +// void onCommandAuthenticateDeviceFinished(); // Process controller notifications/messages void processNetworkFormed(const ZigbeeInterfaceMessage &message); diff --git a/libnymea-zigbee/nxp/zigbeenodenxp.cpp b/libnymea-zigbee/nxp/zigbeenodenxp.cpp new file mode 100644 index 0000000..c58fc02 --- /dev/null +++ b/libnymea-zigbee/nxp/zigbeenodenxp.cpp @@ -0,0 +1,6 @@ +#include "zigbeenodenxp.h" + +ZigbeeNodeNxp::ZigbeeNodeNxp(QObject *parent) : QObject(parent) +{ + +} diff --git a/libnymea-zigbee/nxp/zigbeenodenxp.h b/libnymea-zigbee/nxp/zigbeenodenxp.h new file mode 100644 index 0000000..9d742ce --- /dev/null +++ b/libnymea-zigbee/nxp/zigbeenodenxp.h @@ -0,0 +1,17 @@ +#ifndef ZIGBEENODENXP_H +#define ZIGBEENODENXP_H + +#include +#include "../zigbeenode.h" + +class ZigbeeNodeNxp : public QObject +{ + Q_OBJECT +public: + explicit ZigbeeNodeNxp(QObject *parent = nullptr); + +signals: + +}; + +#endif // ZIGBEENODENXP_H diff --git a/libnymea-zigbee/zigbeenetwork.cpp b/libnymea-zigbee/zigbeenetwork.cpp index 6bf9bc2..93197d0 100644 --- a/libnymea-zigbee/zigbeenetwork.cpp +++ b/libnymea-zigbee/zigbeenetwork.cpp @@ -101,12 +101,12 @@ void ZigbeeNetwork::setExtendedPanId(quint64 extendedPanId) emit extendedPanIdChanged(m_extendedPanId); } -uint ZigbeeNetwork::channel() const +quint32 ZigbeeNetwork::channel() const { return m_channel; } -void ZigbeeNetwork::setChannel(uint channel) +void ZigbeeNetwork::setChannel(quint32 channel) { if (m_channel == channel) return; @@ -244,10 +244,6 @@ void ZigbeeNetwork::loadNetwork() settings.beginGroup("Network"); quint64 extendedPanId = static_cast(settings.value("panId", 0).toULongLong()); - if (extendedPanId == 0) { - extendedPanId = ZigbeeUtils::generateRandomPanId(); - qCDebug(dcZigbeeNetwork()) << "Create new PAN ID" << extendedPanId; - } setExtendedPanId(extendedPanId); setChannel(settings.value("channel", 0).toUInt()); settings.endGroup(); // Network @@ -333,14 +329,6 @@ void ZigbeeNetwork::loadNetwork() void ZigbeeNetwork::clearSettings() { - qCDebug(dcZigbeeNetwork()) << "Clear network settings"; - - // Reset network configurations - m_extendedPanId = 0; - m_channel = 0; - m_securityConfiguration.clear(); - m_nodeType = ZigbeeNode::NodeTypeCoordinator; - qCDebug(dcZigbeeNetwork()) << "Remove zigbee nodes from network"; foreach (ZigbeeNode *node, m_nodes) { removeNode(node); @@ -349,6 +337,13 @@ void ZigbeeNetwork::clearSettings() qCDebug(dcZigbeeNetwork()) << "Clear network settings" << m_settingsFileName; QSettings settings(m_settingsFileName, QSettings::IniFormat, this); settings.clear(); + + // Reset network configurations + qCDebug(dcZigbeeNetwork()) << "Clear network properties"; + m_extendedPanId = 0; + m_channel = 0; + m_securityConfiguration.clear(); + m_nodeType = ZigbeeNode::NodeTypeCoordinator; } void ZigbeeNetwork::saveNode(ZigbeeNode *node) @@ -421,6 +416,11 @@ void ZigbeeNetwork::removeNodeFromSettings(ZigbeeNode *node) settings.endGroup(); // Nodes } +ZigbeeNode *ZigbeeNetwork::createNode(QObject *parent) +{ + return new ZigbeeNode(parent); +} + void ZigbeeNetwork::addNode(ZigbeeNode *node) { qCDebug(dcZigbeeNetwork()) << "Add node" << node; diff --git a/libnymea-zigbee/zigbeenetwork.h b/libnymea-zigbee/zigbeenetwork.h index c38f78d..df92420 100644 --- a/libnymea-zigbee/zigbeenetwork.h +++ b/libnymea-zigbee/zigbeenetwork.h @@ -75,8 +75,8 @@ public: quint64 extendedPanId() const; void setExtendedPanId(quint64 extendedPanId); - uint channel() const; - void setChannel(uint channel); + quint32 channel() const; + void setChannel(quint32 channel); ZigbeeSecurityConfiguration securityConfiguration() const; void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration); @@ -97,7 +97,6 @@ public: private: State m_state = StateUninitialized; - Error m_error = ErrorNoError; // Serial port configuration QString m_serialPortName = "/dev/ttyUSB0"; @@ -105,7 +104,7 @@ private: // Network configurations quint64 m_extendedPanId = 0; - uint m_channel = 0; + quint32 m_channel = 0; ZigbeeSecurityConfiguration m_securityConfiguration; ZigbeeNode::NodeType m_nodeType = ZigbeeNode::NodeTypeCoordinator; bool m_permitJoining = false; @@ -118,6 +117,8 @@ private: void removeNodeInternally(ZigbeeNode *node); protected: + Error m_error = ErrorNoError; + void saveNetwork(); void loadNetwork(); void clearSettings(); @@ -125,6 +126,8 @@ protected: void saveNode(ZigbeeNode *node); void removeNodeFromSettings(ZigbeeNode *node); + ZigbeeNode *createNode(QObject *parent); + void addNode(ZigbeeNode *node); void addUnitializedNode(ZigbeeNode *node); void removeNode(ZigbeeNode *node); diff --git a/libnymea-zigbee/zigbeenetworkmanager.cpp b/libnymea-zigbee/zigbeenetworkmanager.cpp index 33b8477..b7ab633 100644 --- a/libnymea-zigbee/zigbeenetworkmanager.cpp +++ b/libnymea-zigbee/zigbeenetworkmanager.cpp @@ -35,27 +35,29 @@ #include #include -ZigbeeNetworkManager::ZigbeeNetworkManager(const QSerialPortInfo &serialPortInfo, QSerialPort::BaudRate baudrate, BackendType backendType, QObject *parent) : +ZigbeeNetworkManager::ZigbeeNetworkManager(const QString &serialPortName, qint32 baudrate, BackendType backendType, QObject *parent) : QObject(parent), - m_serialPortInfo(serialPortInfo), + m_serialPortName(serialPortName), m_baudrate(baudrate), m_backendType(backendType) { + srand(static_cast(QDateTime::currentMSecsSinceEpoch() / 1000)); + switch (backendType) { case BackendTypeNxp: m_network = new ZigbeeNetworkNxp(this); - m_network->setSerialPortName(m_serialPortInfo.systemLocation()); - m_network->setSerialBaudrate(static_cast(baudrate)); + m_network->setSerialPortName(m_serialPortName); + m_network->setSerialBaudrate(baudrate); break; } } -QSerialPortInfo ZigbeeNetworkManager::serialPortInfo() const +QString ZigbeeNetworkManager::serialPortName() const { - return m_serialPortInfo; + return m_serialPortName; } -QSerialPort::BaudRate ZigbeeNetworkManager::baudrate() const +qint32 ZigbeeNetworkManager::baudrate() const { return m_baudrate; } diff --git a/libnymea-zigbee/zigbeenetworkmanager.h b/libnymea-zigbee/zigbeenetworkmanager.h index dafa648..820ea49 100644 --- a/libnymea-zigbee/zigbeenetworkmanager.h +++ b/libnymea-zigbee/zigbeenetworkmanager.h @@ -45,18 +45,17 @@ public: }; Q_ENUM(BackendType) - explicit ZigbeeNetworkManager(const QSerialPortInfo &serialPortInfo, QSerialPort::BaudRate baudrate, BackendType backendType, QObject *parent = nullptr); + explicit ZigbeeNetworkManager(const QString &serialPortName, qint32 baudrate, BackendType backendType, QObject *parent = nullptr); - QSerialPortInfo serialPortInfo() const; - QSerialPort::BaudRate baudrate() const; + QString serialPortName() const; + qint32 baudrate() const; BackendType backendType() const; ZigbeeNetwork *network() const; - private: - QSerialPortInfo m_serialPortInfo; - QSerialPort::BaudRate m_baudrate; + QString m_serialPortName; + qint32 m_baudrate; BackendType m_backendType = BackendTypeNxp; ZigbeeNetwork *m_network = nullptr; diff --git a/libnymea-zigbee/zigbeeutils.cpp b/libnymea-zigbee/zigbeeutils.cpp index 561f597..826c97b 100644 --- a/libnymea-zigbee/zigbeeutils.cpp +++ b/libnymea-zigbee/zigbeeutils.cpp @@ -170,6 +170,5 @@ QString ZigbeeUtils::profileIdToString(const Zigbee::ZigbeeProfile &profileId) quint64 ZigbeeUtils::generateRandomPanId() { // Note: the PAN ID has to be between 0x0000 and 0x3fff - qsrand(static_cast(QDateTime::currentMSecsSinceEpoch() / 1000)); return static_cast(rand() % (0x3fff - 1) + 1); } diff --git a/nymea-zigbee.pro b/nymea-zigbee.pro index 2fbd465..f2af4eb 100644 --- a/nymea-zigbee.pro +++ b/nymea-zigbee.pro @@ -2,4 +2,3 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS += libnymea-zigbee #zigbee-cli -