Fix deconz init interrupion due to timeout or uart flickering and retry 3 times before giving up
This commit is contained in:
parent
b65386be19
commit
e2d5910e30
@ -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());
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user