Add network node evaluation and readd node if nwk address changed
This commit is contained in:
parent
9e3bbc55ca
commit
4e8254fcb9
Binary file not shown.
Binary file not shown.
BIN
docs/nxp/ZigBee 3.0 Device User Guide - JN-UG-3114.pdf
Normal file
BIN
docs/nxp/ZigBee 3.0 Device User Guide - JN-UG-3114.pdf
Normal file
Binary file not shown.
BIN
docs/nxp/ZigBee Cluster Library User Guide - JN-UG-3115.pdf
Normal file
BIN
docs/nxp/ZigBee Cluster Library User Guide - JN-UG-3115.pdf
Normal file
Binary file not shown.
BIN
docs/nxp/ZigBee Green Power User Guide - JN-UG-3119.pdf
Normal file
BIN
docs/nxp/ZigBee Green Power User Guide - JN-UG-3119.pdf
Normal file
Binary file not shown.
@ -671,8 +671,15 @@ void ZigbeeNetworkDeconz::onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasNode(ieeeAddress)) {
|
if (hasNode(ieeeAddress)) {
|
||||||
qCWarning(dcZigbeeNetwork()) << "Already known device announced. FIXME: Ignoring announcement" << ieeeAddress.toString();
|
ZigbeeNode *node = getZigbeeNode(ieeeAddress);
|
||||||
return;
|
if (shortAddress == node->shortAddress()) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Already known device announced and is reachable again" << node;
|
||||||
|
setNodeReachable(node, true);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Already known device announced with different network address. Removing node and reinitialize...";
|
||||||
|
removeNode(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeNode *node = createNode(shortAddress, ieeeAddress, macCapabilities, this);
|
ZigbeeNode *node = createNode(shortAddress, ieeeAddress, macCapabilities, this);
|
||||||
|
|||||||
@ -88,33 +88,13 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &re
|
|||||||
|
|
||||||
// Finish the reply right the way if the network is offline
|
// Finish the reply right the way if the network is offline
|
||||||
if (!m_controller->available() || state() == ZigbeeNetwork::StateOffline) {
|
if (!m_controller->available() || state() == ZigbeeNetwork::StateOffline) {
|
||||||
finishNetworkReply(reply, ZigbeeNetworkReply::ErrorNetworkOffline);
|
finishReplyInternally(reply, ZigbeeNetworkReply::ErrorNetworkOffline);
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeInterfaceNxpReply *interfaceReply = m_controller->requestSendRequest(request);
|
// Enqueu reply and send next one if we have enouth capacity
|
||||||
connect(interfaceReply, &ZigbeeInterfaceNxpReply::finished, reply, [this, reply, interfaceReply](){
|
m_replyQueue.enqueue(reply);
|
||||||
if (interfaceReply->status() != Nxp::StatusSuccess) {
|
sendNextReply();
|
||||||
qCWarning(dcZigbeeController()) << "Could send request to controller. SQN:" << interfaceReply->sequenceNumber() << interfaceReply->status();
|
|
||||||
finishNetworkReply(reply, ZigbeeNetworkReply::ErrorInterfaceError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: this is a special case for nxp coordinator requests, they don't send a confirm because the request will not be sent trough the network
|
|
||||||
if (reply->request().destinationShortAddress() == 0x0000 && reply->request().profileId() == Zigbee::ZigbeeProfileDevice) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Finish reply since there will be no CONFIRM for local node requests.";
|
|
||||||
finishNetworkReply(reply);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint8 networkRequestId = interfaceReply->responseData().at(0);
|
|
||||||
//qCDebug(dcZigbeeNetwork()) << "Request has network SQN" << networkRequestId;
|
|
||||||
reply->request().setRequestId(networkRequestId);
|
|
||||||
//qCWarning(dcZigbeeNetwork()) << "#### Insert network reply" << reply << "ID:" << networkRequestId << "Current reply count" << m_pendingReplies.count();
|
|
||||||
m_pendingReplies.insert(networkRequestId, reply);
|
|
||||||
// The request has been sent successfully to the device, start the timeout timer now
|
|
||||||
startWaitingReply(reply);
|
|
||||||
});
|
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
@ -191,6 +171,52 @@ void ZigbeeNetworkNxp::setPermitJoining(quint8 duration, quint16 address)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetworkNxp::sendNextReply()
|
||||||
|
{
|
||||||
|
if (m_replyQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_currentReply)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
ZigbeeNetworkReply *reply = m_replyQueue.dequeue();
|
||||||
|
ZigbeeInterfaceNxpReply *interfaceReply = m_controller->requestSendRequest(reply->request());
|
||||||
|
connect(interfaceReply, &ZigbeeInterfaceNxpReply::finished, reply, [this, reply, interfaceReply](){
|
||||||
|
if (interfaceReply->status() != Nxp::StatusSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could send request to controller. SQN:" << interfaceReply->sequenceNumber() << interfaceReply->status();
|
||||||
|
finishReplyInternally(reply, ZigbeeNetworkReply::ErrorInterfaceError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: this is a special case for nxp coordinator requests, they don't send a confirm because the request will not be sent trough the network
|
||||||
|
if (reply->request().destinationShortAddress() == 0x0000 && reply->request().profileId() == Zigbee::ZigbeeProfileDevice) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Finish reply since there will be no CONFIRM for local node requests.";
|
||||||
|
finishReplyInternally(reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 networkRequestId = interfaceReply->responseData().at(0);
|
||||||
|
//qCDebug(dcZigbeeNetwork()) << "Request has network SQN" << networkRequestId;
|
||||||
|
reply->request().setRequestId(networkRequestId);
|
||||||
|
//qCWarning(dcZigbeeNetwork()) << "#### Insert network reply" << reply << "ID:" << networkRequestId << "Current reply count" << m_pendingReplies.count();
|
||||||
|
m_pendingReplies.insert(networkRequestId, reply);
|
||||||
|
// The request has been sent successfully to the device, start the timeout timer now
|
||||||
|
startWaitingReply(reply);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetworkNxp::finishReplyInternally(ZigbeeNetworkReply *reply, ZigbeeNetworkReply::Error error)
|
||||||
|
{
|
||||||
|
finishNetworkReply(reply, error);
|
||||||
|
if (m_currentReply == reply) {
|
||||||
|
m_currentReply = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendNextReply();
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeNetworkReply *ZigbeeNetworkNxp::requestSetPermitJoin(quint16 shortAddress, quint8 duration)
|
ZigbeeNetworkReply *ZigbeeNetworkNxp::requestSetPermitJoin(quint16 shortAddress, quint8 duration)
|
||||||
{
|
{
|
||||||
// Get the power descriptor
|
// Get the power descriptor
|
||||||
@ -410,22 +436,22 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|||||||
connect(coordinatorNode, &ZigbeeNode::stateChanged, this, [this, coordinatorNode](ZigbeeNode::State state){
|
connect(coordinatorNode, &ZigbeeNode::stateChanged, this, [this, coordinatorNode](ZigbeeNode::State state){
|
||||||
if (state == ZigbeeNode::StateInitialized) {
|
if (state == ZigbeeNode::StateInitialized) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
||||||
// ZigbeeClusterGroups *groupsCluster = coordinatorNode->getEndpoint(0x01)->inputCluster<ZigbeeClusterGroups>(ZigbeeClusterLibrary::ClusterIdGroups);
|
// ZigbeeClusterGroups *groupsCluster = coordinatorNode->getEndpoint(0x01)->inputCluster<ZigbeeClusterGroups>(ZigbeeClusterLibrary::ClusterIdGroups);
|
||||||
// if (!groupsCluster) {
|
// if (!groupsCluster) {
|
||||||
// qCWarning(dcZigbeeNetwork()) << "Failed to get groups cluster from coordinator. The coordinator will not be in default group 0x0000";
|
// qCWarning(dcZigbeeNetwork()) << "Failed to get groups cluster from coordinator. The coordinator will not be in default group 0x0000";
|
||||||
// setState(StateRunning);
|
// setState(StateRunning);
|
||||||
// setPermitJoining(0);
|
// setPermitJoining(0);
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// ZigbeeClusterReply *reply = groupsCluster->addGroup(0x0000, "Default");
|
// ZigbeeClusterReply *reply = groupsCluster->addGroup(0x0000, "Default");
|
||||||
// connect(reply, &ZigbeeClusterReply::finished, this, [=](){
|
// connect(reply, &ZigbeeClusterReply::finished, this, [=](){
|
||||||
// if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
|
// if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||||
// qCWarning(dcZigbeeNetwork()) << "Failed to add coordinator to default group 0x0000. The coordinator will not be in default group 0x0000";
|
// qCWarning(dcZigbeeNetwork()) << "Failed to add coordinator to default group 0x0000. The coordinator will not be in default group 0x0000";
|
||||||
// }
|
// }
|
||||||
// setState(StateRunning);
|
// setState(StateRunning);
|
||||||
// setPermitJoining(0);
|
// setPermitJoining(0);
|
||||||
// });
|
// });
|
||||||
|
|
||||||
setState(StateRunning);
|
setState(StateRunning);
|
||||||
setPermitJoining(0);
|
setPermitJoining(0);
|
||||||
@ -581,8 +607,15 @@ void ZigbeeNetworkNxp::onDeviceAnnounced(quint16 shortAddress, ZigbeeAddress iee
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasNode(ieeeAddress)) {
|
if (hasNode(ieeeAddress)) {
|
||||||
qCWarning(dcZigbeeNetwork()) << "Already known device announced. FIXME: Ignoring announcement" << ieeeAddress.toString();
|
ZigbeeNode *node = getZigbeeNode(ieeeAddress);
|
||||||
return;
|
if (shortAddress == node->shortAddress()) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Already known device announced and is reachable again" << node;
|
||||||
|
setNodeReachable(node, true);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Already known device announced with different network address. Removing node and reinitialize...";
|
||||||
|
removeNode(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeNode *node = createNode(shortAddress, ieeeAddress, macCapabilities, this);
|
ZigbeeNode *node = createNode(shortAddress, ieeeAddress, macCapabilities, this);
|
||||||
|
|||||||
@ -51,9 +51,15 @@ public:
|
|||||||
private:
|
private:
|
||||||
ZigbeeBridgeControllerNxp *m_controller = nullptr;
|
ZigbeeBridgeControllerNxp *m_controller = nullptr;
|
||||||
bool m_networkRunning = false;
|
bool m_networkRunning = false;
|
||||||
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
|
||||||
int m_reconnectCounter = 0;
|
|
||||||
|
|
||||||
|
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
||||||
|
QQueue<ZigbeeNetworkReply *> m_replyQueue;
|
||||||
|
ZigbeeNetworkReply *m_currentReply = nullptr;
|
||||||
|
|
||||||
|
void sendNextReply();
|
||||||
|
void finishReplyInternally(ZigbeeNetworkReply *reply, ZigbeeNetworkReply::Error error = ZigbeeNetworkReply::ErrorNoError);
|
||||||
|
|
||||||
|
int m_reconnectCounter = 0;
|
||||||
bool processVersionReply(ZigbeeInterfaceNxpReply *reply);
|
bool processVersionReply(ZigbeeInterfaceNxpReply *reply);
|
||||||
|
|
||||||
// ZDO
|
// ZDO
|
||||||
|
|||||||
@ -323,7 +323,8 @@ public:
|
|||||||
ZigbeeNwkLayerStatusRouteDiscoveryFailed = 0xd0,
|
ZigbeeNwkLayerStatusRouteDiscoveryFailed = 0xd0,
|
||||||
ZigbeeNwkLayerStatusRouteError = 0xd1,
|
ZigbeeNwkLayerStatusRouteError = 0xd1,
|
||||||
ZigbeeNwkLayerStatusBtTableFull = 0xd2,
|
ZigbeeNwkLayerStatusBtTableFull = 0xd2,
|
||||||
ZigbeeNwkLayerStatusFrameNotBuffered = 0xd3
|
ZigbeeNwkLayerStatusFrameNotBuffered = 0xd3,
|
||||||
|
ZigbeeNwkLayerStatusFrameBuffered = 0xd4
|
||||||
};
|
};
|
||||||
Q_ENUM(ZigbeeNwkLayerStatus)
|
Q_ENUM(ZigbeeNwkLayerStatus)
|
||||||
|
|
||||||
|
|||||||
@ -53,13 +53,21 @@ ZigbeeNetwork::ZigbeeNetwork(const QUuid &networkUuid, QObject *parent) :
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
m_reachableRefreshTimer = new QTimer(this);
|
||||||
|
m_reachableRefreshTimer->setInterval(300000);
|
||||||
|
m_reachableRefreshTimer->setSingleShot(false);
|
||||||
|
connect(m_reachableRefreshTimer, &QTimer::timeout, this, &ZigbeeNetwork::evaluateNodeReachableStates);
|
||||||
|
|
||||||
connect(this, &ZigbeeNetwork::stateChanged, this, [this](ZigbeeNetwork::State state){
|
connect(this, &ZigbeeNetwork::stateChanged, this, [this](ZigbeeNetwork::State state){
|
||||||
if (state != ZigbeeNetwork::StateRunning) {
|
if (state == ZigbeeNetwork::StateRunning) {
|
||||||
|
evaluateNodeReachableStates();
|
||||||
|
m_reachableRefreshTimer->start();
|
||||||
|
} else {
|
||||||
foreach (ZigbeeNode *node, m_nodes) {
|
foreach (ZigbeeNode *node, m_nodes) {
|
||||||
node->setReachable(false);
|
node->setReachable(false);
|
||||||
}
|
}
|
||||||
|
m_reachableRefreshTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,6 +557,11 @@ void ZigbeeNetwork::removeUninitializedNode(ZigbeeNode *node)
|
|||||||
node->deleteLater();
|
node->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setNodeReachable(ZigbeeNode *node, bool reachable)
|
||||||
|
{
|
||||||
|
node->setReachable(reachable);
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeNetwork::setState(ZigbeeNetwork::State state)
|
void ZigbeeNetwork::setState(ZigbeeNetwork::State state)
|
||||||
{
|
{
|
||||||
if (m_state == state)
|
if (m_state == state)
|
||||||
@ -599,7 +612,7 @@ void ZigbeeNetwork::setReplyResponseError(ZigbeeNetworkReply *reply, Zigbee::Zig
|
|||||||
} else {
|
} else {
|
||||||
// There has been an error while transporting the request to the device
|
// There has been an error while transporting the request to the device
|
||||||
// Note: if the APS status is >= 0xc1, it has to interpreted as NWK layer error
|
// Note: if the APS status is >= 0xc1, it has to interpreted as NWK layer error
|
||||||
if (zigbeeApsStatus >= 0xc1 && zigbeeApsStatus <= 0xd3) {
|
if (zigbeeApsStatus >= 0xc1 && zigbeeApsStatus <= 0xd4) {
|
||||||
reply->m_zigbeeNwkStatus = static_cast<Zigbee::ZigbeeNwkLayerStatus>(static_cast<quint8>(zigbeeApsStatus));
|
reply->m_zigbeeNwkStatus = static_cast<Zigbee::ZigbeeNwkLayerStatus>(static_cast<quint8>(zigbeeApsStatus));
|
||||||
finishNetworkReply(reply, ZigbeeNetworkReply::ErrorZigbeeNwkStatusError);
|
finishNetworkReply(reply, ZigbeeNetworkReply::ErrorZigbeeNwkStatusError);
|
||||||
} else if (zigbeeApsStatus >= 0xE0 && zigbeeApsStatus <= 0xF4) {
|
} else if (zigbeeApsStatus >= 0xE0 && zigbeeApsStatus <= 0xF4) {
|
||||||
@ -662,6 +675,32 @@ void ZigbeeNetwork::onNodeClusterAttributeChanged(ZigbeeCluster *cluster, const
|
|||||||
m_database->saveAttribute(cluster, attribute);
|
m_database->saveAttribute(cluster, attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::evaluateNodeReachableStates()
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Evaluate reachable state of nodes";
|
||||||
|
foreach (ZigbeeNode *node, m_nodes) {
|
||||||
|
if (node->macCapabilities().receiverOnWhenIdle && node->shortAddress() != 0x0000) {
|
||||||
|
ZigbeeDeviceObjectReply *zdoReply = node->deviceObject()->requestMgmtLqi();
|
||||||
|
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, this, [=](){
|
||||||
|
if (zdoReply->error()) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << node << "seems not to be reachable" << zdoReply->error();
|
||||||
|
setNodeReachable(node, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Note: sleeping devices should send some message within 6 hours,
|
||||||
|
// otherwise the device might not be reachable any more
|
||||||
|
int msSinceLastSeen = node->lastSeen().msecsTo(QDateTime::currentDateTimeUtc());
|
||||||
|
qCDebug(dcZigbeeNetwork()) << node << "last seen" << QTime::fromMSecsSinceStartOfDay(msSinceLastSeen).toString();
|
||||||
|
if (msSinceLastSeen < 1000*60*60*6) {
|
||||||
|
setNodeReachable(node, true);
|
||||||
|
} else {
|
||||||
|
setNodeReachable(node, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, ZigbeeNetwork *network)
|
QDebug operator<<(QDebug debug, ZigbeeNetwork *network)
|
||||||
{
|
{
|
||||||
debug.nospace().noquote() << "ZigbeeNetwork(" << network->macAddress().toString() << ", "
|
debug.nospace().noquote() << "ZigbeeNetwork(" << network->macAddress().toString() << ", "
|
||||||
|
|||||||
@ -175,6 +175,8 @@ protected:
|
|||||||
quint8 m_permitJoiningDuration = 120;
|
quint8 m_permitJoiningDuration = 120;
|
||||||
quint8 m_permitJoiningRemaining = 0;
|
quint8 m_permitJoiningRemaining = 0;
|
||||||
|
|
||||||
|
QTimer *m_reachableRefreshTimer = nullptr;
|
||||||
|
|
||||||
void setPermitJoiningEnabled(bool permitJoiningEnabled);
|
void setPermitJoiningEnabled(bool permitJoiningEnabled);
|
||||||
void setPermitJoiningDuration(quint8 duration);
|
void setPermitJoiningDuration(quint8 duration);
|
||||||
void setPermitJoiningRemaining(quint8 remaining);
|
void setPermitJoiningRemaining(quint8 remaining);
|
||||||
@ -188,6 +190,8 @@ protected:
|
|||||||
void removeNode(ZigbeeNode *node);
|
void removeNode(ZigbeeNode *node);
|
||||||
void removeUninitializedNode(ZigbeeNode *node);
|
void removeUninitializedNode(ZigbeeNode *node);
|
||||||
|
|
||||||
|
void setNodeReachable(ZigbeeNode *node, bool reachable);
|
||||||
|
|
||||||
void setState(State state);
|
void setState(State state);
|
||||||
void setError(Error error);
|
void setError(Error error);
|
||||||
|
|
||||||
@ -227,6 +231,7 @@ signals:
|
|||||||
private slots:
|
private slots:
|
||||||
void onNodeStateChanged(ZigbeeNode::State state);
|
void onNodeStateChanged(ZigbeeNode::State state);
|
||||||
void onNodeClusterAttributeChanged(ZigbeeCluster *cluster, const ZigbeeClusterAttribute &attribute);
|
void onNodeClusterAttributeChanged(ZigbeeCluster *cluster, const ZigbeeClusterAttribute &attribute);
|
||||||
|
void evaluateNodeReachableStates();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void startNetwork() = 0;
|
virtual void startNetwork() = 0;
|
||||||
|
|||||||
@ -244,7 +244,7 @@ void ZigbeeNode::initNodeDescriptor()
|
|||||||
m_requestRetry++;
|
m_requestRetry++;
|
||||||
if (m_requestRetry < 3) {
|
if (m_requestRetry < 3) {
|
||||||
qCDebug(dcZigbeeNode()) << "Retry to request node descriptor" << m_requestRetry << "/" << "3";
|
qCDebug(dcZigbeeNode()) << "Retry to request node descriptor" << m_requestRetry << "/" << "3";
|
||||||
initNodeDescriptor();
|
QTimer::singleShot(1000, this, [=](){ initNodeDescriptor(); });
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcZigbeeNode()) << "Failed to read node descriptor from" << this << "after 3 attempts. Giving up.";
|
qCWarning(dcZigbeeNode()) << "Failed to read node descriptor from" << this << "after 3 attempts. Giving up.";
|
||||||
m_requestRetry = 0;
|
m_requestRetry = 0;
|
||||||
@ -273,7 +273,7 @@ void ZigbeeNode::initPowerDescriptor()
|
|||||||
if (m_requestRetry < 3) {
|
if (m_requestRetry < 3) {
|
||||||
m_requestRetry++;
|
m_requestRetry++;
|
||||||
qCDebug(dcZigbeeNode()) << "Retry to request power descriptor from" << this << m_requestRetry << "/" << "3 attempts.";
|
qCDebug(dcZigbeeNode()) << "Retry to request power descriptor from" << this << m_requestRetry << "/" << "3 attempts.";
|
||||||
initPowerDescriptor();
|
QTimer::singleShot(1000, this, [=](){ initPowerDescriptor(); });
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcZigbeeNode()) << "Failed to read power descriptor from" << this << "after 3 attempts. Giving up.";
|
qCWarning(dcZigbeeNode()) << "Failed to read power descriptor from" << this << "after 3 attempts. Giving up.";
|
||||||
m_requestRetry = 0;
|
m_requestRetry = 0;
|
||||||
@ -305,7 +305,7 @@ void ZigbeeNode::initEndpoints()
|
|||||||
if (m_requestRetry < 3) {
|
if (m_requestRetry < 3) {
|
||||||
m_requestRetry++;
|
m_requestRetry++;
|
||||||
qCDebug(dcZigbeeNode()) << "Retry to request active endpoints from" << this << m_requestRetry << "/" << "3 attempts.";
|
qCDebug(dcZigbeeNode()) << "Retry to request active endpoints from" << this << m_requestRetry << "/" << "3 attempts.";
|
||||||
initEndpoints();
|
QTimer::singleShot(1000, this, [=](){ initEndpoints(); });
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcZigbeeNode()) << "Failed to read active endpoints from" << this << "after 3 attempts. Giving up.";
|
qCWarning(dcZigbeeNode()) << "Failed to read active endpoints from" << this << "after 3 attempts. Giving up.";
|
||||||
m_requestRetry = 0;
|
m_requestRetry = 0;
|
||||||
@ -355,7 +355,7 @@ void ZigbeeNode::initEndpoint(quint8 endpointId)
|
|||||||
if (m_requestRetry < 3) {
|
if (m_requestRetry < 3) {
|
||||||
m_requestRetry++;
|
m_requestRetry++;
|
||||||
qCDebug(dcZigbeeNode()) << "Retry to request simple descriptor from" << this << ZigbeeUtils::convertByteToHexString(endpointId) << m_requestRetry << "/" << "3 attempts.";
|
qCDebug(dcZigbeeNode()) << "Retry to request simple descriptor from" << this << ZigbeeUtils::convertByteToHexString(endpointId) << m_requestRetry << "/" << "3 attempts.";
|
||||||
initEndpoint(endpointId);
|
QTimer::singleShot(1000, this, [=](){ initEndpoint(endpointId); });
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcZigbeeNode()) << "Failed to read simple descriptor from" << this << ZigbeeUtils::convertByteToHexString(endpointId) << "after 3 attempts. Giving up.";
|
qCWarning(dcZigbeeNode()) << "Failed to read simple descriptor from" << this << ZigbeeUtils::convertByteToHexString(endpointId) << "after 3 attempts. Giving up.";
|
||||||
m_requestRetry = 0;
|
m_requestRetry = 0;
|
||||||
@ -721,7 +721,19 @@ QDebug operator<<(QDebug debug, ZigbeeNode *node)
|
|||||||
{
|
{
|
||||||
debug.nospace().noquote() << "ZigbeeNode(" << ZigbeeUtils::convertUint16ToHexString(node->shortAddress());
|
debug.nospace().noquote() << "ZigbeeNode(" << ZigbeeUtils::convertUint16ToHexString(node->shortAddress());
|
||||||
debug.nospace().noquote() << ", " << node->extendedAddress().toString();
|
debug.nospace().noquote() << ", " << node->extendedAddress().toString();
|
||||||
debug.nospace().noquote() << ", RX on:" << node->macCapabilities().receiverOnWhenIdle;
|
switch (node->nodeDescriptor().nodeType) {
|
||||||
|
case ZigbeeDeviceProfile::NodeTypeCoordinator:
|
||||||
|
debug.nospace().noquote() << ", Coordinator";
|
||||||
|
break;
|
||||||
|
case ZigbeeDeviceProfile::NodeTypeRouter:
|
||||||
|
debug.nospace().noquote() << ", Router";
|
||||||
|
break;
|
||||||
|
case ZigbeeDeviceProfile::NodeTypeEndDevice:
|
||||||
|
debug.nospace().noquote() << ", End device";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.nospace().noquote() << ", RxOn:" << node->macCapabilities().receiverOnWhenIdle;
|
||||||
debug.nospace().noquote() << ")";
|
debug.nospace().noquote() << ")";
|
||||||
return debug.space().quote();
|
return debug.space().quote();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,6 +56,9 @@ public:
|
|||||||
Q_ENUM(State)
|
Q_ENUM(State)
|
||||||
|
|
||||||
State state() const;
|
State state() const;
|
||||||
|
|
||||||
|
// Note: For sleepy devices this indicates best effort.
|
||||||
|
// If a device does not send any data within 6h, it will be assumed to no reachable
|
||||||
bool reachable() const;
|
bool reachable() const;
|
||||||
|
|
||||||
QUuid networkUuid() const;
|
QUuid networkUuid() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user