Restored basic network starting and resetting

This commit is contained in:
Simon Stürz 2020-02-28 11:41:03 +01:00
parent 899ad4e3b9
commit 7c7ba4f13a
11 changed files with 230 additions and 193 deletions

View File

@ -10,6 +10,7 @@ SOURCES += \
nxp/interface/zigbeeinterfacereply.cpp \ nxp/interface/zigbeeinterfacereply.cpp \
nxp/zigbeenetworknxp.cpp \ nxp/zigbeenetworknxp.cpp \
nxp/zigbeebridgecontrollernxp.cpp \ nxp/zigbeebridgecontrollernxp.cpp \
nxp/zigbeenodenxp.cpp \
zigbeecluster.cpp \ zigbeecluster.cpp \
zigbeeclusterattribute.cpp \ zigbeeclusterattribute.cpp \
zigbeenetwork.cpp \ zigbeenetwork.cpp \
@ -29,6 +30,7 @@ HEADERS += \
nxp/interface/zigbeeinterfacereply.h \ nxp/interface/zigbeeinterfacereply.h \
nxp/zigbeenetworknxp.h \ nxp/zigbeenetworknxp.h \
nxp/zigbeebridgecontrollernxp.h \ nxp/zigbeebridgecontrollernxp.h \
nxp/zigbeenodenxp.h \
zigbeecluster.h \ zigbeecluster.h \
zigbeeclusterattribute.h \ zigbeeclusterattribute.h \
zigbeenetwork.h \ zigbeenetwork.h \

View File

@ -24,7 +24,19 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state)
m_networkRunning = false; m_networkRunning = false;
qCDebug(dcZigbeeNetwork()) << "Starting state changed: Erase persistant data"; qCDebug(dcZigbeeNetwork()) << "Starting state changed: Erase persistant data";
ZigbeeInterfaceReply *reply = m_controller->commandErasePersistantData(); 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; break;
} }
case StartingStateReset: { case StartingStateReset: {
@ -38,7 +50,18 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state)
// }); // });
qCDebug(dcZigbeeNetwork()) << "Starting state changed: Reset controller"; qCDebug(dcZigbeeNetwork()) << "Starting state changed: Reset controller";
ZigbeeInterfaceReply *reply = m_controller->commandResetController(); 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; break;
} }
case StartingStateGetVersion: { case StartingStateGetVersion: {
@ -52,7 +75,17 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state)
setExtendedPanId(ZigbeeUtils::generateRandomPanId()); setExtendedPanId(ZigbeeUtils::generateRandomPanId());
} }
ZigbeeInterfaceReply *reply = m_controller->commandSetExtendedPanId(extendedPanId()); 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; break;
} }
case StartingStateSetChannel: { case StartingStateSetChannel: {
@ -74,19 +107,49 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state)
qCDebug(dcZigbeeNetwork()) << "Using channel" << channel() << "for the zigbee network."; qCDebug(dcZigbeeNetwork()) << "Using channel" << channel() << "for the zigbee network.";
reply = m_controller->commandSetChannelMask(channelMask); 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; break;
} }
case StartingStateSetSecurity: { case StartingStateSetSecurity: {
qCDebug(dcZigbeeNetwork()) << "Starting state changed: Set security configuration"; qCDebug(dcZigbeeNetwork()) << "Starting state changed: Set security configuration";
ZigbeeInterfaceReply *reply = m_controller->commandSetSecurityStateAndKey(4, 0, 1, "5A6967426565416C6C69616E63653039"); 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; break;
} }
case StartingStateSetNodeType: { case StartingStateSetNodeType: {
qCDebug(dcZigbeeNetwork()) << "Starting state changed: Set node type"; qCDebug(dcZigbeeNetwork()) << "Starting state changed: Set node type";
ZigbeeInterfaceReply *reply = m_controller->commandSetNodeType(ZigbeeNode::NodeTypeCoordinator); 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; break;
} }
case StartingStateStartNetwork: { case StartingStateStartNetwork: {
@ -95,11 +158,6 @@ void ZigbeeNetworkNxp::setStartingState(ZigbeeNetworkNxp::StartingState state)
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandStartNetworkFinished); connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkNxp::onCommandStartNetworkFinished);
break; break;
} }
case StartingStateGetPermitJoinStatus: {
qCDebug(dcZigbeeNetwork()) << "Starting state changed: Get permit join status";
readPermitJoinStatus();
break;
}
case StartingStateReadeNodeDescriptor: { case StartingStateReadeNodeDescriptor: {
qCDebug(dcZigbeeNetwork()) << "Starting state changed: Read coordinator node descriptor"; qCDebug(dcZigbeeNetwork()) << "Starting state changed: Read coordinator node descriptor";
//ZigbeeInterfaceReply *reply = m_controller->commandNodeDescriptorRequest(0x0000); //ZigbeeInterfaceReply *reply = m_controller->commandNodeDescriptorRequest(0x0000);
@ -140,7 +198,8 @@ void ZigbeeNetworkNxp::readControllerVersion()
//m_controllerFirmwareVersion = QString("%1.%2").arg(majorVersion).arg(minorVersion); //m_controllerFirmwareVersion = QString("%1.%2").arg(majorVersion).arg(minorVersion);
qCDebug(dcZigbeeNetwork()) << "Controller version:" << 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(); qCDebug(dcZigbeeController()) << reply->additionalMessage();
setPermitJoining(static_cast<bool>(reply->additionalMessage().data().at(0))); setPermitJoining(static_cast<bool>(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; 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) void ZigbeeNetworkNxp::processNodeClusterList(const ZigbeeInterfaceMessage &message)
@ -463,7 +523,7 @@ void ZigbeeNetworkNxp::processAttributeReport(const ZigbeeInterfaceMessage &mess
QByteArray attributeData = data.right(dataSize); QByteArray attributeData = data.right(dataSize);
if (attributeData.length() != 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. // Note: the NXP firmware for JN5169 has a bug here and does not send the attributeStatus.
// Repars data without attribute status // Repars data without attribute status
sequenceNumber = 0; sequenceNumber = 0;
@ -504,13 +564,13 @@ void ZigbeeNetworkNxp::processAttributeReport(const ZigbeeInterfaceMessage &mess
} }
// FIXME // FIXME
// ZigbeeNode *node = getZigbeeNode(sourceAddress); // ZigbeeNode *node = getZigbeeNode(sourceAddress);
// if (!node) { // if (!node) {
// qCWarning(dcZigbeeNode()) << "Received an attribute report from an unknown node. Ignoring data."; // qCWarning(dcZigbeeNode()) << "Received an attribute report from an unknown node. Ignoring data.";
// return; // return;
// } // }
// node->setClusterAttribute(static_cast<Zigbee::ClusterId>(clusterId), ZigbeeClusterAttribute(attributeId, dataType, attributeData)); // node->setClusterAttribute(static_cast<Zigbee::ClusterId>(clusterId), ZigbeeClusterAttribute(attributeId, dataType, attributeData));
} }
void ZigbeeNetworkNxp::processLeaveIndication(const ZigbeeInterfaceMessage &message) void ZigbeeNetworkNxp::processLeaveIndication(const ZigbeeInterfaceMessage &message)
@ -566,7 +626,8 @@ void ZigbeeNetworkNxp::processRestartProvisioned(const ZigbeeInterfaceMessage &m
if (m_startingState == StartingStateReset) { if (m_startingState == StartingStateReset) {
if (m_networkRunning) { if (m_networkRunning) {
qCDebug(dcZigbeeNetwork()) << "Reset finished. Network already running. No need to set it up"; qCDebug(dcZigbeeNetwork()) << "Reset finished. Network already running. No need to set it up";
setStartingState(StartingStateGetPermitJoinStatus); // FIXME: get network status
//setStartingState(StartingStateGetPermitJoinStatus);
} else { } else {
qCDebug(dcZigbeeNetwork()) << "Reset finished. Set up network"; qCDebug(dcZigbeeNetwork()) << "Reset finished. Set up network";
setStartingState(StartingStateGetVersion); setStartingState(StartingStateGetVersion);
@ -637,16 +698,16 @@ void ZigbeeNetworkNxp::onControllerAvailableChanged(bool available)
if (!available) { if (!available) {
// FIXME // FIXME
// foreach (ZigbeeNode *node, nodes()) { // foreach (ZigbeeNode *node, nodes()) {
// node->setConnected(false); // node->setConnected(false);
// } // }
setError(ErrorHardwareUnavailable); setError(ErrorHardwareUnavailable);
setPermitJoining(false); setPermitJoining(false);
setState(StateOffline); setState(StateOffline);
setStartingState(StartingStateNone); setStartingState(StartingStateNone);
} else { } else {
setError(ErrorNoError); m_error = ErrorNoError;
setState(StateStarting); setState(StateStarting);
setStartingState(StartingStateReset); setStartingState(StartingStateReset);
} }
@ -704,66 +765,6 @@ void ZigbeeNetworkNxp::onCommandSoftResetControllerFinished()
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
} }
void ZigbeeNetworkNxp::onCommandErasePersistentDataFinished()
{
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
reply->deleteLater();
if (reply->status() != ZigbeeInterfaceReply::Success) {
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
return;
}
m_factoryResetting = false;
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
if (m_startingState == StartingStateErase) {
setStartingState(StartingStateReset);
}
}
void ZigbeeNetworkNxp::onCommandSetExtendedPanIdFinished()
{
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
reply->deleteLater();
if (reply->status() != ZigbeeInterfaceReply::Success) {
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
return;
}
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
if (m_startingState == StartingStateSetPanId) setStartingState(StartingStateSetChannel);
}
void ZigbeeNetworkNxp::onCommandSetChannelMaskFinished()
{
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(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<ZigbeeInterfaceReply *>(sender());
reply->deleteLater();
if (reply->status() != ZigbeeInterfaceReply::Success) {
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
return;
}
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
if (m_startingState == StartingStateSetNodeType) setStartingState(StartingStateStartNetwork);
}
void ZigbeeNetworkNxp::onCommandStartNetworkFinished() void ZigbeeNetworkNxp::onCommandStartNetworkFinished()
{ {
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender()); ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
@ -777,7 +778,8 @@ void ZigbeeNetworkNxp::onCommandStartNetworkFinished()
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully"; qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
qCDebug(dcZigbeeController()) << reply->additionalMessage(); qCDebug(dcZigbeeController()) << reply->additionalMessage();
processNetworkFormed(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() void ZigbeeNetworkNxp::onCommandStartScanFinished()
@ -809,80 +811,70 @@ void ZigbeeNetworkNxp::onCommandRequestMatchDescriptorFinished()
qCDebug(dcZigbeeController()) << reply->additionalMessage(); qCDebug(dcZigbeeController()) << reply->additionalMessage();
} }
void ZigbeeNetworkNxp::onCommandSetSecurityFinished()
{
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
reply->deleteLater();
if (reply->status() != ZigbeeInterfaceReply::Success) {
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
return;
}
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
if (m_startingState == StartingStateSetSecurity) setStartingState(StartingStateSetNodeType);
}
void ZigbeeNetworkNxp::processNetworkFormed(const ZigbeeInterfaceMessage &message) void ZigbeeNetworkNxp::processNetworkFormed(const ZigbeeInterfaceMessage &message)
{ {
// Parse network status // Parse network status
QByteArray data = message.data(); QByteArray data = message.data();
quint8 networkStatus = static_cast<quint8>(data.at(0));
QString networkStatusString;
bool success = false; quint8 networkStatus = 0;
quint16 shortAddress = 0;
quint64 extendedAddress = 0;
quint8 currentChannel = 0;
if (networkStatus == 0) { QDataStream stream(&data, QIODevice::ReadOnly);
networkStatusString = "joined"; stream >> networkStatus >> shortAddress >> extendedAddress >> currentChannel;
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";
}
if (!success) { QString networkStatusString;
qCWarning(dcZigbeeNetwork()) << "Forming network failed" << networkStatusString; if (networkStatus == 0) {
setPermitJoining(false); networkStatusString = "joined";
setStartingState(StartingStateNone); } else if (networkStatus == 1) {
setState(StateOffline); networkStatusString = "formed";
setError(ErrorZigbeeError); } else if (networkStatus >= 128 && networkStatus <= 244) {
m_networkRunning = false; networkStatusString = "failed: Zigbee event code: " + QString::number(networkStatus);
return; } else {
} networkStatusString = "unknown";
}
quint16 shortAddress = ZigbeeUtils::convertByteArrayToUint16(data.mid(1, 2)); if (networkStatus != Zigbee::ZigbeeNwkLayerStatusJointNetwork && networkStatus != Zigbee::ZigbeeNwkLayerStatusFormedNetwork) {
quint64 extendedAddress = ZigbeeUtils::convertByteArrayToUint64(data.mid(3, 8)); qCWarning(dcZigbeeNetwork()) << "Forming network failed" << networkStatusString;
setPermitJoining(false);
setStartingState(StartingStateNone);
setState(StateOffline);
setError(ErrorZigbeeError);
m_networkRunning = false;
return;
}
// Parse network channel setChannel(currentChannel);
quint8 channel = static_cast<quint8>(data.at(11));
qCDebug(dcZigbeeNetwork()).noquote() << "Network" << networkStatusString; // Parse network channel
qCDebug(dcZigbeeNetwork()) << " Extended PAN ID:" << extendedPanId(); qCDebug(dcZigbeeNetwork()).noquote() << "Network" << networkStatusString;
qCDebug(dcZigbeeNetwork()) << " Address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress); qCDebug(dcZigbeeNetwork()) << " Extended PAN ID:" << extendedPanId();
qCDebug(dcZigbeeNetwork()) << " Extended address:" << ZigbeeAddress(extendedAddress); qCDebug(dcZigbeeNetwork()) << " Address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress);
qCDebug(dcZigbeeNetwork()) << " Channel:" << channel; qCDebug(dcZigbeeNetwork()) << " Extended address:" << ZigbeeAddress(extendedAddress);
qCDebug(dcZigbeeNetwork()) << " Permit joining:" << permitJoining(); 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 // FIXME: create coordinator node
// setShortAddress(shortAddress);
// setExtendedAddress(ZigbeeAddress(extendedAddress));
// setChannel(channel);
// if (!hasNode(this->shortAddress())) // // Set the node information
// addUnitializedNode(this); // setShortAddress(shortAddress);
// setExtendedAddress(ZigbeeAddress(extendedAddress));
// setChannel(channel);
// if (!hasNode(this->shortAddress()))
// addUnitializedNode(this);
} }
void ZigbeeNetworkNxp::startNetwork() void ZigbeeNetworkNxp::startNetwork()
{ {
// FIXME: define if router or coordinator
qCDebug(dcZigbeeNetwork()) << "Start network..."; qCDebug(dcZigbeeNetwork()) << "Start network...";
if (m_controller) { if (m_controller) {
qCDebug(dcZigbeeNetwork()) << "Clean up old controller..."; qCDebug(dcZigbeeNetwork()) << "Clean up old controller...";
@ -890,7 +882,7 @@ void ZigbeeNetworkNxp::startNetwork()
m_controller = nullptr; m_controller = nullptr;
} }
qCDebug(dcZigbeeNetwork()) << "Create new controller..."; qCDebug(dcZigbeeNetwork()) << "Create new controller..." << state();
m_controller = new ZigbeeBridgeControllerNxp(this); m_controller = new ZigbeeBridgeControllerNxp(this);
connect(m_controller, &ZigbeeBridgeControllerNxp::messageReceived, this, &ZigbeeNetworkNxp::onMessageReceived); connect(m_controller, &ZigbeeBridgeControllerNxp::messageReceived, this, &ZigbeeNetworkNxp::onMessageReceived);
connect(m_controller, &ZigbeeBridgeControllerNxp::availableChanged, this, &ZigbeeNetworkNxp::onControllerAvailableChanged); connect(m_controller, &ZigbeeBridgeControllerNxp::availableChanged, this, &ZigbeeNetworkNxp::onControllerAvailableChanged);
@ -898,16 +890,39 @@ void ZigbeeNetworkNxp::startNetwork()
if (state() == StateUninitialized) if (state() == StateUninitialized)
loadNetwork(); 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())) { if (!m_controller->enable(serialPortName(), serialBaudrate())) {
setPermitJoining(false); setPermitJoining(false);
setState(StateOffline); setState(StateOffline);
setStartingState(StartingStateNone); setStartingState(StartingStateNone);
setError(ErrorHardwareUnavailable); setError(ErrorHardwareUnavailable);
} else { return;
// Reset
setStartingState(StartingStateReset);
setState(StateStarting);
} }
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() void ZigbeeNetworkNxp::stopNetwork()
@ -928,9 +943,10 @@ void ZigbeeNetworkNxp::stopNetwork()
void ZigbeeNetworkNxp::factoryResetNetwork() void ZigbeeNetworkNxp::factoryResetNetwork()
{ {
qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone."; qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone.";
m_factoryResetting = true;
clearSettings(); clearSettings();
setState(StateUninitialized);
setState(StateStarting); qCDebug(dcZigbeeNetwork()) << "The factory reset is finished. Start restart with a fresh network.";
setStartingState(StartingStateErase); startNetwork();
} }

View File

@ -22,7 +22,6 @@ private:
StartingStateSetSecurity, StartingStateSetSecurity,
StartingStateSetNodeType, StartingStateSetNodeType,
StartingStateStartNetwork, StartingStateStartNetwork,
StartingStateGetPermitJoinStatus,
StartingStateReadeNodeDescriptor, StartingStateReadeNodeDescriptor,
StartingStateReadPowerDescriptor StartingStateReadPowerDescriptor
}; };
@ -43,13 +42,9 @@ private slots:
// Controller command finished slots // Controller command finished slots
void onCommandResetControllerFinished(); void onCommandResetControllerFinished();
void onCommandSoftResetControllerFinished(); void onCommandSoftResetControllerFinished();
void onCommandErasePersistentDataFinished();
void onCommandSetExtendedPanIdFinished();
void onCommandSetChannelMaskFinished();
void onCommandSetNodeTypeFinished();
void onCommandStartNetworkFinished(); void onCommandStartNetworkFinished();
void onCommandStartScanFinished(); void onCommandStartScanFinished();
void onCommandEnableWhitelistFinished(); //void onCommandEnableWhitelistFinished();
// void onCommandNodeDescriptorRequestFinished(); // void onCommandNodeDescriptorRequestFinished();
// void onCommandSimpleDescriptorRequestFinished(); // void onCommandSimpleDescriptorRequestFinished();
@ -60,9 +55,8 @@ private slots:
void onCommandRequestLinkQualityFinished(); void onCommandRequestLinkQualityFinished();
void onCommandRequestMatchDescriptorFinished(); void onCommandRequestMatchDescriptorFinished();
void onCommandSetSecurityFinished(); // void onCommandNetworkAddressRequestFinished();
void onCommandNetworkAddressRequestFinished(); // void onCommandAuthenticateDeviceFinished();
void onCommandAuthenticateDeviceFinished();
// Process controller notifications/messages // Process controller notifications/messages
void processNetworkFormed(const ZigbeeInterfaceMessage &message); void processNetworkFormed(const ZigbeeInterfaceMessage &message);

View File

@ -0,0 +1,6 @@
#include "zigbeenodenxp.h"
ZigbeeNodeNxp::ZigbeeNodeNxp(QObject *parent) : QObject(parent)
{
}

View File

@ -0,0 +1,17 @@
#ifndef ZIGBEENODENXP_H
#define ZIGBEENODENXP_H
#include <QObject>
#include "../zigbeenode.h"
class ZigbeeNodeNxp : public QObject
{
Q_OBJECT
public:
explicit ZigbeeNodeNxp(QObject *parent = nullptr);
signals:
};
#endif // ZIGBEENODENXP_H

View File

@ -101,12 +101,12 @@ void ZigbeeNetwork::setExtendedPanId(quint64 extendedPanId)
emit extendedPanIdChanged(m_extendedPanId); emit extendedPanIdChanged(m_extendedPanId);
} }
uint ZigbeeNetwork::channel() const quint32 ZigbeeNetwork::channel() const
{ {
return m_channel; return m_channel;
} }
void ZigbeeNetwork::setChannel(uint channel) void ZigbeeNetwork::setChannel(quint32 channel)
{ {
if (m_channel == channel) if (m_channel == channel)
return; return;
@ -244,10 +244,6 @@ void ZigbeeNetwork::loadNetwork()
settings.beginGroup("Network"); settings.beginGroup("Network");
quint64 extendedPanId = static_cast<quint64>(settings.value("panId", 0).toULongLong()); quint64 extendedPanId = static_cast<quint64>(settings.value("panId", 0).toULongLong());
if (extendedPanId == 0) {
extendedPanId = ZigbeeUtils::generateRandomPanId();
qCDebug(dcZigbeeNetwork()) << "Create new PAN ID" << extendedPanId;
}
setExtendedPanId(extendedPanId); setExtendedPanId(extendedPanId);
setChannel(settings.value("channel", 0).toUInt()); setChannel(settings.value("channel", 0).toUInt());
settings.endGroup(); // Network settings.endGroup(); // Network
@ -333,14 +329,6 @@ void ZigbeeNetwork::loadNetwork()
void ZigbeeNetwork::clearSettings() 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"; qCDebug(dcZigbeeNetwork()) << "Remove zigbee nodes from network";
foreach (ZigbeeNode *node, m_nodes) { foreach (ZigbeeNode *node, m_nodes) {
removeNode(node); removeNode(node);
@ -349,6 +337,13 @@ void ZigbeeNetwork::clearSettings()
qCDebug(dcZigbeeNetwork()) << "Clear network settings" << m_settingsFileName; qCDebug(dcZigbeeNetwork()) << "Clear network settings" << m_settingsFileName;
QSettings settings(m_settingsFileName, QSettings::IniFormat, this); QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
settings.clear(); 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) void ZigbeeNetwork::saveNode(ZigbeeNode *node)
@ -421,6 +416,11 @@ void ZigbeeNetwork::removeNodeFromSettings(ZigbeeNode *node)
settings.endGroup(); // Nodes settings.endGroup(); // Nodes
} }
ZigbeeNode *ZigbeeNetwork::createNode(QObject *parent)
{
return new ZigbeeNode(parent);
}
void ZigbeeNetwork::addNode(ZigbeeNode *node) void ZigbeeNetwork::addNode(ZigbeeNode *node)
{ {
qCDebug(dcZigbeeNetwork()) << "Add node" << node; qCDebug(dcZigbeeNetwork()) << "Add node" << node;

View File

@ -75,8 +75,8 @@ public:
quint64 extendedPanId() const; quint64 extendedPanId() const;
void setExtendedPanId(quint64 extendedPanId); void setExtendedPanId(quint64 extendedPanId);
uint channel() const; quint32 channel() const;
void setChannel(uint channel); void setChannel(quint32 channel);
ZigbeeSecurityConfiguration securityConfiguration() const; ZigbeeSecurityConfiguration securityConfiguration() const;
void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration); void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration);
@ -97,7 +97,6 @@ public:
private: private:
State m_state = StateUninitialized; State m_state = StateUninitialized;
Error m_error = ErrorNoError;
// Serial port configuration // Serial port configuration
QString m_serialPortName = "/dev/ttyUSB0"; QString m_serialPortName = "/dev/ttyUSB0";
@ -105,7 +104,7 @@ private:
// Network configurations // Network configurations
quint64 m_extendedPanId = 0; quint64 m_extendedPanId = 0;
uint m_channel = 0; quint32 m_channel = 0;
ZigbeeSecurityConfiguration m_securityConfiguration; ZigbeeSecurityConfiguration m_securityConfiguration;
ZigbeeNode::NodeType m_nodeType = ZigbeeNode::NodeTypeCoordinator; ZigbeeNode::NodeType m_nodeType = ZigbeeNode::NodeTypeCoordinator;
bool m_permitJoining = false; bool m_permitJoining = false;
@ -118,6 +117,8 @@ private:
void removeNodeInternally(ZigbeeNode *node); void removeNodeInternally(ZigbeeNode *node);
protected: protected:
Error m_error = ErrorNoError;
void saveNetwork(); void saveNetwork();
void loadNetwork(); void loadNetwork();
void clearSettings(); void clearSettings();
@ -125,6 +126,8 @@ protected:
void saveNode(ZigbeeNode *node); void saveNode(ZigbeeNode *node);
void removeNodeFromSettings(ZigbeeNode *node); void removeNodeFromSettings(ZigbeeNode *node);
ZigbeeNode *createNode(QObject *parent);
void addNode(ZigbeeNode *node); void addNode(ZigbeeNode *node);
void addUnitializedNode(ZigbeeNode *node); void addUnitializedNode(ZigbeeNode *node);
void removeNode(ZigbeeNode *node); void removeNode(ZigbeeNode *node);

View File

@ -35,27 +35,29 @@
#include <QDataStream> #include <QDataStream>
#include <QSettings> #include <QSettings>
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), QObject(parent),
m_serialPortInfo(serialPortInfo), m_serialPortName(serialPortName),
m_baudrate(baudrate), m_baudrate(baudrate),
m_backendType(backendType) m_backendType(backendType)
{ {
srand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000));
switch (backendType) { switch (backendType) {
case BackendTypeNxp: case BackendTypeNxp:
m_network = new ZigbeeNetworkNxp(this); m_network = new ZigbeeNetworkNxp(this);
m_network->setSerialPortName(m_serialPortInfo.systemLocation()); m_network->setSerialPortName(m_serialPortName);
m_network->setSerialBaudrate(static_cast<qint32>(baudrate)); m_network->setSerialBaudrate(baudrate);
break; 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; return m_baudrate;
} }

View File

@ -45,18 +45,17 @@ public:
}; };
Q_ENUM(BackendType) 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; QString serialPortName() const;
QSerialPort::BaudRate baudrate() const; qint32 baudrate() const;
BackendType backendType() const; BackendType backendType() const;
ZigbeeNetwork *network() const; ZigbeeNetwork *network() const;
private: private:
QSerialPortInfo m_serialPortInfo; QString m_serialPortName;
QSerialPort::BaudRate m_baudrate; qint32 m_baudrate;
BackendType m_backendType = BackendTypeNxp; BackendType m_backendType = BackendTypeNxp;
ZigbeeNetwork *m_network = nullptr; ZigbeeNetwork *m_network = nullptr;

View File

@ -170,6 +170,5 @@ QString ZigbeeUtils::profileIdToString(const Zigbee::ZigbeeProfile &profileId)
quint64 ZigbeeUtils::generateRandomPanId() quint64 ZigbeeUtils::generateRandomPanId()
{ {
// Note: the PAN ID has to be between 0x0000 and 0x3fff // Note: the PAN ID has to be between 0x0000 and 0x3fff
qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000));
return static_cast<quint64>(rand() % (0x3fff - 1) + 1); return static_cast<quint64>(rand() % (0x3fff - 1) + 1);
} }

View File

@ -2,4 +2,3 @@ TEMPLATE = subdirs
CONFIG += ordered CONFIG += ordered
SUBDIRS += libnymea-zigbee #zigbee-cli SUBDIRS += libnymea-zigbee #zigbee-cli