Merge PR #80: Rework the reachable refreshing and manual LQI/RTG fetching
commit
d5df291bf3
|
|
@ -52,12 +52,12 @@ ZigbeeNetwork::ZigbeeNetwork(const QUuid &networkUuid, QObject *parent) :
|
||||||
});
|
});
|
||||||
|
|
||||||
m_reachableRefreshTimer = new QTimer(this);
|
m_reachableRefreshTimer = new QTimer(this);
|
||||||
m_reachableRefreshTimer->setInterval(120000);
|
m_reachableRefreshTimer->setInterval(60000);
|
||||||
connect(m_reachableRefreshTimer, &QTimer::timeout, this, &ZigbeeNetwork::evaluateNodeReachableStates);
|
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();
|
refreshNeighborTables();
|
||||||
m_reachableRefreshTimer->start();
|
m_reachableRefreshTimer->start();
|
||||||
} else {
|
} else {
|
||||||
foreach (ZigbeeNode *node, m_nodes) {
|
foreach (ZigbeeNode *node, m_nodes) {
|
||||||
|
|
@ -334,10 +334,10 @@ void ZigbeeNetwork::refreshNeighborTables()
|
||||||
{
|
{
|
||||||
foreach (ZigbeeNode *node, m_nodes) {
|
foreach (ZigbeeNode *node, m_nodes) {
|
||||||
if (node->macCapabilities().receiverOnWhenIdle) {
|
if (node->macCapabilities().receiverOnWhenIdle) {
|
||||||
m_refreshNeighborTableAddresses.append(node->extendedAddress());
|
m_refreshLqiAndRtgTablesAddresses.append(node->extendedAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fetchNextNodeLqiTable();
|
fetchNextNodeLqiAndRtgTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetwork::printNetwork()
|
void ZigbeeNetwork::printNetwork()
|
||||||
|
|
@ -467,21 +467,18 @@ ZigbeeNode *ZigbeeNetwork::createNode(quint16 shortAddress, const ZigbeeAddress
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetwork::fetchNextNodeLqiTable()
|
void ZigbeeNetwork::fetchNextNodeLqiAndRtgTables()
|
||||||
{
|
{
|
||||||
ZigbeeNode *node = nullptr;
|
ZigbeeNode *node = nullptr;
|
||||||
while (!node && !m_refreshNeighborTableAddresses.isEmpty()) {
|
while (!node && !m_refreshLqiAndRtgTablesAddresses.isEmpty()) {
|
||||||
node = getZigbeeNode(m_refreshNeighborTableAddresses.takeFirst());
|
node = getZigbeeNode(m_refreshLqiAndRtgTablesAddresses.takeFirst());
|
||||||
}
|
|
||||||
while (!node && !m_reachableRefreshAddresses.isEmpty()) {
|
|
||||||
node = getZigbeeNode(m_reachableRefreshAddresses.takeFirst());
|
|
||||||
}
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
// Nothing to do...
|
// Nothing to do...
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Refreshing LQI neighbor table for node" << node->shortAddress() << node->modelName();
|
qCDebug(dcZigbeeNetwork()) << "Fetching LQI and RTG tables for node" << node->shortAddress() << node->modelName();
|
||||||
|
|
||||||
// Make a lqi request in order to check if the node is reachable
|
// Make a lqi request in order to check if the node is reachable
|
||||||
ZigbeeReply *reply = node->readLqiTableEntries();
|
ZigbeeReply *reply = node->readLqiTableEntries();
|
||||||
|
|
@ -489,20 +486,15 @@ void ZigbeeNetwork::fetchNextNodeLqiTable()
|
||||||
if (reply->error()) {
|
if (reply->error()) {
|
||||||
qCWarning(dcZigbeeNetwork()) << node << "seems not to be reachable" << reply->error();
|
qCWarning(dcZigbeeNetwork()) << node << "seems not to be reachable" << reply->error();
|
||||||
setNodeReachable(node, false);
|
setNodeReachable(node, false);
|
||||||
|
fetchNextNodeLqiAndRtgTables();
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
setNodeReachable(node, true);
|
setNodeReachable(node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeReply *reply = node->readRoutingTableEntries();
|
ZigbeeReply *reply = node->readRoutingTableEntries();
|
||||||
connect(reply, &ZigbeeReply::finished, this, [=]() {
|
connect(reply, &ZigbeeReply::finished, this, [=]() {
|
||||||
|
fetchNextNodeLqiAndRtgTables();
|
||||||
// While we still need to refresh neighbor tables, send the next request right away...
|
|
||||||
if (!m_refreshNeighborTableAddresses.isEmpty()) {
|
|
||||||
fetchNextNodeLqiTable();
|
|
||||||
} else {
|
|
||||||
// ... else be easier on the resources for the cyclic refresh
|
|
||||||
QTimer::singleShot(5000, this, &ZigbeeNetwork::fetchNextNodeLqiTable);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -958,16 +950,15 @@ void ZigbeeNetwork::evaluateNodeReachableStates()
|
||||||
|
|
||||||
foreach (ZigbeeNode *node, m_nodes) {
|
foreach (ZigbeeNode *node, m_nodes) {
|
||||||
if (node->shortAddress() == 0x0000) {
|
if (node->shortAddress() == 0x0000) {
|
||||||
// While we wouldn't need to check ourselves for being reachable, do it nevertheless so we keep the
|
continue;
|
||||||
// neighbor table in sync which is useful in logs
|
}
|
||||||
if (!m_reachableRefreshAddresses.contains(node->extendedAddress())) {
|
|
||||||
m_reachableRefreshAddresses.append(node->extendedAddress());
|
if (m_reachableRefreshAddresses.contains(node->extendedAddress())) {
|
||||||
}
|
// Node is already scheduled for refresh
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->macCapabilities().receiverOnWhenIdle) {
|
if (node->macCapabilities().receiverOnWhenIdle) {
|
||||||
|
|
||||||
// Lets send a request to all things which are not reachable
|
// Lets send a request to all things which are not reachable
|
||||||
if (!node->reachable()) {
|
if (!node->reachable()) {
|
||||||
if (!m_reachableRefreshAddresses.contains(node->extendedAddress())) {
|
if (!m_reachableRefreshAddresses.contains(node->extendedAddress())) {
|
||||||
|
|
@ -980,8 +971,7 @@ void ZigbeeNetwork::evaluateNodeReachableStates()
|
||||||
// Lets send a request to nodes which have not been seen more than 10 min
|
// Lets send a request to nodes which have not been seen more than 10 min
|
||||||
qulonglong msSinceLastSeen = node->lastSeen().msecsTo(QDateTime::currentDateTimeUtc());
|
qulonglong msSinceLastSeen = node->lastSeen().msecsTo(QDateTime::currentDateTimeUtc());
|
||||||
qCDebug(dcZigbeeNetwork()) << node << "has been seen the last time" << QTime::fromMSecsSinceStartOfDay(msSinceLastSeen).toString() << "ago.";
|
qCDebug(dcZigbeeNetwork()) << node << "has been seen the last time" << QTime::fromMSecsSinceStartOfDay(msSinceLastSeen).toString() << "ago.";
|
||||||
// 10 min = 10 * 60 * 1000 = 600000 ms
|
if (msSinceLastSeen > 60 * 60 * 1000) { // 1 hour
|
||||||
if (msSinceLastSeen > 600000 && !m_reachableRefreshAddresses.contains(node->extendedAddress())) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << node << "has not been seen in" << (msSinceLastSeen / 1000 / 60) << "minutes. Scheduling LQI request.";
|
qCDebug(dcZigbeeNetwork()) << node << "has not been seen in" << (msSinceLastSeen / 1000 / 60) << "minutes. Scheduling LQI request.";
|
||||||
m_reachableRefreshAddresses.append(node->extendedAddress());
|
m_reachableRefreshAddresses.append(node->extendedAddress());
|
||||||
}
|
}
|
||||||
|
|
@ -999,7 +989,26 @@ void ZigbeeNetwork::evaluateNodeReachableStates()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchNextNodeLqiTable();
|
ZigbeeNode *node = nullptr;
|
||||||
|
while (!node && !m_reachableRefreshAddresses.isEmpty()) {
|
||||||
|
node = getZigbeeNode(m_reachableRefreshAddresses.takeFirst());
|
||||||
|
}
|
||||||
|
if (!node) {
|
||||||
|
// Nothing to do...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a lqi request in order to check if the node is reachable
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Polling Node" << node->shortAddress() << node->manufacturerName() << node->modelName() << "for reachability";
|
||||||
|
ZigbeeReply *reply = node->readLqiTableEntries();
|
||||||
|
connect(reply, &ZigbeeReply::finished, this, [=](){
|
||||||
|
if (reply->error()) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << node << "seems not to be reachable" << reply->error();
|
||||||
|
setNodeReachable(node, false);
|
||||||
|
} else {
|
||||||
|
setNodeReachable(node, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, ZigbeeNetwork *network)
|
QDebug operator<<(QDebug debug, ZigbeeNetwork *network)
|
||||||
|
|
|
||||||
|
|
@ -187,8 +187,9 @@ protected:
|
||||||
|
|
||||||
QTimer *m_reachableRefreshTimer = nullptr;
|
QTimer *m_reachableRefreshTimer = nullptr;
|
||||||
QList<ZigbeeAddress> m_reachableRefreshAddresses;
|
QList<ZigbeeAddress> m_reachableRefreshAddresses;
|
||||||
QList<ZigbeeAddress> m_refreshNeighborTableAddresses;
|
|
||||||
void fetchNextNodeLqiTable();
|
void fetchNextNodeLqiAndRtgTables();
|
||||||
|
QList<ZigbeeAddress> m_refreshLqiAndRtgTablesAddresses;
|
||||||
|
|
||||||
void setPermitJoiningState(bool permitJoiningEnabled, quint8 duration = 0);
|
void setPermitJoiningState(bool permitJoiningEnabled, quint8 duration = 0);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue