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;
}
// APS data indication received, process the content
qCDebug(dcZigbeeController()) << "Reading data indication finished successfully" << "SQN:" << reply->sequenceNumber();
processDataIndication(reply->responseData());

View File

@ -294,8 +294,19 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
qCDebug(dcZigbeeController()) << "Configured network key successfully. SQN:" << reply->sequenceNumber();
}
// Configuration finished, lets start the network
setCreateNetworkState(CreateNetworkStateStartNetwork);
// Re-read the configurations
// 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.";
m_database->saveNode(m_coordinatorNode);
m_initializing = false;
setNodeInformation(m_coordinatorNode, "deCONZ", "", bridgeController()->firmwareVersion());
setState(StateRunning);
setPermitJoining(0);
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 network configuration parameters
// - Read the network state
@ -403,9 +405,18 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
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;
}
m_initRetry = 0;
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
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)
{
if (!available) {

View File

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

View File

@ -393,7 +393,6 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
setNodeInformation(m_coordinatorNode, "NXP", "JN516x", bridgeController()->firmwareVersion());
m_database->saveNode(m_coordinatorNode);
setPermitJoining(0);
setState(StateRunning);
return;
@ -448,11 +447,8 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
case ZigbeeBridgeControllerNxp::ControllerStateRunningUninitialized: {
// Create the database if there is no database available
setState(StateStarting);
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);
}
initializeDatabase();
qCDebug(dcZigbeeNetwork()) << "Request controller version";
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();

View File

@ -455,6 +455,15 @@ void ZigbeeNetwork::removeNodeInternally(ZigbeeNode *node)
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)
{
return new ZigbeeNode(this, shortAddress, extendedAddress, parent);
@ -627,6 +636,8 @@ void ZigbeeNetwork::setNodeInformation(ZigbeeNode *node, const QString &manufact
node->m_version = version;
emit node->versionChanged(node->version());
m_database->saveNode(m_coordinatorNode);
}
void ZigbeeNetwork::setState(ZigbeeNetwork::State state)

View File

@ -138,6 +138,9 @@ private:
qint32 m_serialBaudrate = 115200;
ZigbeeAddress m_macAddress;
ZigbeeNetworkDatabase *m_database = nullptr;
bool m_networkLoaded = false;
// Continuous ASP sequence number for network requests
quint8 m_sequenceNumber = 0;
@ -164,8 +167,8 @@ protected:
Error m_error = ErrorNoError;
ZigbeeNode *m_coordinatorNode = nullptr;
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, quint8 macCapabilities, QObject *parent);