Fix deconz init interrupion due to timeout or uart flickering and retry 3 times before giving up

This commit is contained in:
Simon Stürz 2020-12-14 18:49:24 +01:00
parent b65386be19
commit e2d5910e30
6 changed files with 64 additions and 24 deletions

View File

@ -767,7 +767,6 @@ void ZigbeeBridgeControllerDeconz::readDataIndication()
return; return;
} }
// APS data indication received, process the content // APS data indication received, process the content
qCDebug(dcZigbeeController()) << "Reading data indication finished successfully" << "SQN:" << reply->sequenceNumber(); qCDebug(dcZigbeeController()) << "Reading data indication finished successfully" << "SQN:" << reply->sequenceNumber();
processDataIndication(reply->responseData()); processDataIndication(reply->responseData());

View File

@ -294,8 +294,19 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
qCDebug(dcZigbeeController()) << "Configured network key successfully. SQN:" << reply->sequenceNumber(); qCDebug(dcZigbeeController()) << "Configured network key successfully. SQN:" << reply->sequenceNumber();
} }
// Configuration finished, lets start the network // Re-read the configurations
setCreateNetworkState(CreateNetworkStateStartNetwork); // Read all network parameters
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
qCWarning(dcZigbeeController()) << "Could not read network parameters during network start up. SQN:" << reply->sequenceNumber() << reply->statusCode();
}
qCDebug(dcZigbeeController()) << m_controller->networkConfiguration();
// Configuration finished, lets start the network
setCreateNetworkState(CreateNetworkStateStartNetwork);
});
}); });
}); });
}); });
@ -351,8 +362,9 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
} }
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done."; qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
m_database->saveNode(m_coordinatorNode);
m_initializing = false; m_initializing = false;
setNodeInformation(m_coordinatorNode, "deCONZ", "", bridgeController()->firmwareVersion());
setState(StateRunning); setState(StateRunning);
setPermitJoining(0); setPermitJoining(0);
return; return;
@ -378,18 +390,8 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
} }
} }
void ZigbeeNetworkDeconz::startNetworkInternally() void ZigbeeNetworkDeconz::runNetworkInitProcess()
{ {
qCDebug(dcZigbeeNetwork()) << "Start zigbee network internally";
m_createNewNetwork = false;
// Check if we have to create a pan ID and select the channel
if (panId() == 0 || !m_coordinatorNode) {
qCDebug(dcZigbeeNetwork()) << "Generate new extended PAN ID...";
setExtendedPanId(ZigbeeUtils::generateRandomPanId());
m_createNewNetwork = true;
}
// - Read the firmware version // - Read the firmware version
// - Read the network configuration parameters // - Read the network configuration parameters
// - Read the network state // - Read the network state
@ -403,9 +405,18 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){ connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
if (reply->statusCode() != Deconz::StatusCodeSuccess) { if (reply->statusCode() != Deconz::StatusCodeSuccess) {
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode(); qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
// FIXME: set an appropriate error m_initRetry++;
if (m_initRetry < 3) {
qCDebug(dcZigbeeNetwork()) << "Retry to initialize network" << m_initRetry << "/ 3";
runNetworkInitProcess();
} else {
qCWarning(dcZigbeeNetwork()) << "Failed to read firmware version after 3 attempts. Giving up";
m_controller->disable();
}
return; return;
} }
m_initRetry = 0;
qCDebug(dcZigbeeNetwork()) << "Version request finished successfully" << ZigbeeUtils::convertByteArrayToHexString(reply->responseData()); qCDebug(dcZigbeeNetwork()) << "Version request finished successfully" << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
// Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order // Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order
quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3)); quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3));
@ -498,6 +509,22 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
}); });
} }
void ZigbeeNetworkDeconz::startNetworkInternally()
{
qCDebug(dcZigbeeNetwork()) << "Start zigbee network internally";
m_createNewNetwork = false;
// Check if we have to create a pan ID and select the channel
if (panId() == 0 || !m_coordinatorNode) {
qCDebug(dcZigbeeNetwork()) << "Generate new extended PAN ID...";
setExtendedPanId(ZigbeeUtils::generateRandomPanId());
m_createNewNetwork = true;
}
m_initRetry = 0;
runNetworkInitProcess();
}
void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available) void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
{ {
if (!available) { if (!available) {

View File

@ -71,6 +71,10 @@ private:
QTimer *m_pollNetworkStateTimer = nullptr; QTimer *m_pollNetworkStateTimer = nullptr;
void setCreateNetworkState(CreateNetworkState state); void setCreateNetworkState(CreateNetworkState state);
// Init procedure
int m_initRetry = 0;
void runNetworkInitProcess();
ZigbeeNetworkReply *requestSetPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe); ZigbeeNetworkReply *requestSetPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
protected: protected:

View File

@ -393,7 +393,6 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done."; qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
setNodeInformation(m_coordinatorNode, "NXP", "JN516x", bridgeController()->firmwareVersion()); setNodeInformation(m_coordinatorNode, "NXP", "JN516x", bridgeController()->firmwareVersion());
m_database->saveNode(m_coordinatorNode);
setPermitJoining(0); setPermitJoining(0);
setState(StateRunning); setState(StateRunning);
return; return;
@ -448,11 +447,8 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
case ZigbeeBridgeControllerNxp::ControllerStateRunningUninitialized: { case ZigbeeBridgeControllerNxp::ControllerStateRunningUninitialized: {
// Create the database if there is no database available // Create the database if there is no database available
setState(StateStarting); setState(StateStarting);
if (!m_database) {
QString networkDatabaseFileName = settingsDirectory().absolutePath() + QDir::separator() + QString("zigbee-network-%1.db").arg(networkUuid().toString().remove('{').remove('}')); initializeDatabase();
qCDebug(dcZigbeeNetwork()) << "Using ZigBee network database" << QFileInfo(networkDatabaseFileName).fileName();
m_database = new ZigbeeNetworkDatabase(this, networkDatabaseFileName, this);
}
qCDebug(dcZigbeeNetwork()) << "Request controller version"; qCDebug(dcZigbeeNetwork()) << "Request controller version";
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion(); ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();

View File

@ -455,6 +455,15 @@ void ZigbeeNetwork::removeNodeInternally(ZigbeeNode *node)
node->deleteLater(); node->deleteLater();
} }
void ZigbeeNetwork::initializeDatabase()
{
if (!m_database) {
QString networkDatabaseFileName = settingsDirectory().absolutePath() + QDir::separator() + QString("zigbee-network-%1.db").arg(networkUuid().toString().remove('{').remove('}'));
qCDebug(dcZigbeeNetwork()) << "Using ZigBee network database" << QFileInfo(networkDatabaseFileName).fileName();
m_database = new ZigbeeNetworkDatabase(this, networkDatabaseFileName, this);
}
}
ZigbeeNode *ZigbeeNetwork::createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, QObject *parent) ZigbeeNode *ZigbeeNetwork::createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, QObject *parent)
{ {
return new ZigbeeNode(this, shortAddress, extendedAddress, parent); return new ZigbeeNode(this, shortAddress, extendedAddress, parent);
@ -627,6 +636,8 @@ void ZigbeeNetwork::setNodeInformation(ZigbeeNode *node, const QString &manufact
node->m_version = version; node->m_version = version;
emit node->versionChanged(node->version()); emit node->versionChanged(node->version());
m_database->saveNode(m_coordinatorNode);
} }
void ZigbeeNetwork::setState(ZigbeeNetwork::State state) void ZigbeeNetwork::setState(ZigbeeNetwork::State state)

View File

@ -138,6 +138,9 @@ private:
qint32 m_serialBaudrate = 115200; qint32 m_serialBaudrate = 115200;
ZigbeeAddress m_macAddress; ZigbeeAddress m_macAddress;
ZigbeeNetworkDatabase *m_database = nullptr;
bool m_networkLoaded = false;
// Continuous ASP sequence number for network requests // Continuous ASP sequence number for network requests
quint8 m_sequenceNumber = 0; quint8 m_sequenceNumber = 0;
@ -164,8 +167,8 @@ protected:
Error m_error = ErrorNoError; Error m_error = ErrorNoError;
ZigbeeNode *m_coordinatorNode = nullptr; ZigbeeNode *m_coordinatorNode = nullptr;
ZigbeeSecurityConfiguration m_securityConfiguration; ZigbeeSecurityConfiguration m_securityConfiguration;
ZigbeeNetworkDatabase *m_database = nullptr;
bool m_networkLoaded = false; void initializeDatabase();
ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, QObject *parent); ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, QObject *parent);
ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, quint8 macCapabilities, QObject *parent); ZigbeeNode *createNode(quint16 shortAddress, const ZigbeeAddress &extendedAddress, quint8 macCapabilities, QObject *parent);