Skip to content

Commit c96a005

Browse files
committed
Bring back NWK discovery requests
There are networks where the neighbor table based approach to discver the network may not work. The heavy weight NWK broadcasts are a last resort to reach routers. The handling is delayed until receive errors for unicasts reach a threshold.
1 parent 4834fbe commit c96a005

2 files changed

Lines changed: 37 additions & 101 deletions

File tree

src/zm_controller.cpp

Lines changed: 36 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ namespace {
126126
const int MaxApsBusyRequests = 6;
127127
const int TickMs = zmController::MainTickMs;
128128
const int MaxRecvErrors = 5;
129-
const int MaxRecvErrorsZombie = 10;
129+
const int MaxRecvErrorsZombie = 8;
130130
constexpr deCONZ::TimeSeconds MaxTimeOut{60};
131131
constexpr deCONZ::TimeSeconds MaxConfirmedTimeOut{10};
132132
const int MaxZdpTimeout = 3;
@@ -138,6 +138,8 @@ namespace {
138138
}
139139

140140
static bool ZCL_IsDefaultResponse(const deCONZ::ApsDataRequest &req);
141+
bool ZDP_SendNwkAddrRequest(zmController *apsCtrl, const deCONZ::Address &dst);
142+
bool ZDP_SendIeeeAddrRequest(zmController *apsCtrl, const deCONZ::Address &dst);
141143

142144
bool NodeInfo::operator <(const NodeInfo &other) const
143145
{
@@ -1749,7 +1751,7 @@ void zmController::nodeKeyPressed(uint64_t extAddr, int key)
17491751
}
17501752
else if (key == deCONZ::NodeKeyRequestNwkAddress)
17511753
{
1752-
if (sendNwkAddrRequest(node))
1754+
if (ZDP_SendNwkAddrRequest(this, node->data->address()))
17531755
{
17541756
}
17551757
}
@@ -6281,9 +6283,9 @@ void zmController::deleteNode(NodeInfo *node, NodeRemoveMode finally)
62816283
}
62826284

62836285

6284-
bool zmController::sendNwkAddrRequest(NodeInfo *node)
6286+
bool ZDP_SendNwkAddrRequest(zmController *apsCtrl, const deCONZ::Address &dst)
62856287
{
6286-
if (!node || !node->data)
6288+
if (!apsCtrl || !dst.hasExt())
62876289
{
62886290
return false;
62896291
}
@@ -6293,16 +6295,16 @@ bool zmController::sendNwkAddrRequest(NodeInfo *node)
62936295
req.setDstEndpoint(ZDO_ENDPOINT);
62946296
req.setSrcEndpoint(ZDO_ENDPOINT);
62956297
req.setDstAddressMode(deCONZ::ApsNwkAddress);
6296-
req.dstAddress().setExt(node->data->address().ext()); // reference
6298+
req.dstAddress().setExt(dst.ext()); // reference
62976299
req.dstAddress().setNwk(deCONZ::BroadcastRxOnWhenIdle);
62986300
req.setProfileId(ZDP_PROFILE_ID);
62996301
req.setClusterId(ZDP_NWK_ADDR_CLID);
63006302
req.setRadius(0);
63016303

63026304
QDataStream stream(&req.asdu(), QIODevice::WriteOnly);
63036305
stream.setByteOrder(QDataStream::LittleEndian);
6304-
stream << genSequenceNumber(); // seq no.
6305-
stream << (quint64)node->data->address().ext(); // device address
6306+
stream << apsCtrl->genSequenceNumber(); // seq no.
6307+
stream << (quint64)dst.ext(); // device address
63066308

63076309
//uint8_t requestType = 0x01; // extended request
63086310
uint8_t requestType = 0x00; // single device request
@@ -6311,16 +6313,12 @@ bool zmController::sendNwkAddrRequest(NodeInfo *node)
63116313
stream << requestType;
63126314
stream << startIndex;
63136315

6314-
if (apsdeDataRequest(req) == deCONZ::Success)
6316+
if (apsCtrl->apsdeDataRequest(req) == deCONZ::Success)
63156317
{
6316-
// DBG_Printf(DBG_ZDP, "send NWK_addr_req to %s, last seen %" PRId64 " s, last seen by neighbors %" PRId64 " s\n",
6317-
// node->data->extAddressString().c_str(), (int64_t)(node->data->lastSeenElapsed() / 1000), (node->data->lastSeenByNeighbor() / 1000));
63186318
return true;
63196319
}
6320-
else
6321-
{
6322-
DBG_Printf(DBG_ZDP, "failed to send NWK_Addr_req to %s\n", node->data->extAddressString().c_str());
6323-
}
6320+
6321+
DBG_Printf(DBG_ZDP, "failed to send NWK_Addr_req to " FMT_MAC "\n", FMT_MAC_CAST(dst.ext()));
63246322

63256323
return false;
63266324
}
@@ -6361,42 +6359,6 @@ bool ZDP_SendIeeeAddrRequest(zmController *apsCtrl, const deCONZ::Address &dst)
63616359
return false;
63626360
}
63636361

6364-
bool zmController::sendIeeeAddrRequest(NodeInfo *node)
6365-
{
6366-
if (!node || !node->data)
6367-
{
6368-
return false;
6369-
}
6370-
6371-
// unicast to the node, if the node answers it will be marked as non-zombie
6372-
// in the APS-DATA.indication
6373-
ApsDataRequest req;
6374-
QDataStream stream(&req.asdu(), QIODevice::WriteOnly);
6375-
stream.setByteOrder(QDataStream::LittleEndian);
6376-
6377-
req.dstAddress().setNwk(node->data->address().nwk());
6378-
req.setDstAddressMode(deCONZ::ApsNwkAddress);
6379-
6380-
req.setDstEndpoint(ZDO_ENDPOINT);
6381-
req.setSrcEndpoint(ZDO_ENDPOINT);
6382-
req.setProfileId(ZDP_PROFILE_ID);
6383-
// req.setTxOptions(deCONZ::ApsTxAcknowledgedTransmission);
6384-
req.setRadius(0);
6385-
req.setClusterId(ZDP_IEEE_ADDR_CLID);
6386-
stream << genSequenceNumber();
6387-
stream << node->data->address().nwk();
6388-
6389-
stream << (uint8_t)0x00; // single request type
6390-
stream << (uint8_t)0x00; // ignore start index
6391-
6392-
if (apsdeDataRequest(req) == deCONZ::Success)
6393-
{
6394-
return true;
6395-
}
6396-
6397-
return false;
6398-
}
6399-
64006362
bool zmController::sendMgtmLqiRequest(NodeInfo *node)
64016363
{
64026364
if (!node || !node->data)
@@ -9092,11 +9054,21 @@ void zmController::deviceDiscoverTick()
90929054

90939055
NodeInfo &node = m_nodes[m_lqiIter];
90949056

9095-
if (!node.data || node.data->isZombie() || node.data->isEndDevice() ||
9057+
if (!node.data || node.data->isEndDevice() ||
90969058
node.data->isInWaitState() || !node.data->address().hasNwk())
90979059
{
90989060
m_lqiIter++;
90999061
}
9062+
else if (node.data->isZombie() || 2 < node.data->recvErrors())
9063+
{
9064+
m_lqiIter++;
9065+
9066+
AddressPair addressPair;
9067+
addressPair.bAddr = node.data->address();
9068+
addressPair.bMacCapabilities = node.data->nodeDescriptor().macCapabilities();
9069+
9070+
addDeviceDiscover(addressPair);
9071+
}
91009072
else if (isValid(node.data->lastSeen()) || node.data->lastSeenByNeighbor() < 9000 ||
91019073
(!node.data->sourceRoutes().empty() && node.data->sourceRoutes().front().errors() < 1))
91029074
{
@@ -9152,48 +9124,6 @@ void zmController::deviceDiscoverTick()
91529124
m_discoverIter = 0;
91539125
}
91549126

9155-
#if 0 // TODO(mpi): reactivate?!
9156-
NodeInfo *node = &m_nodes[m_discoverIter];
9157-
if (getParameter(deCONZ::ParamPermitJoin) > 0)
9158-
{
9159-
// wait
9160-
}
9161-
else if (node->data && !node->data->isZombie() && m_apsRequestQueue.size() < 2 && node->data->nodeDescriptor().receiverOnWhenIdle())
9162-
{
9163-
if (isValid(node->data->lastSeen()) && node->data->lastSeenElapsed() < (1000 * 60 * 8) &&
9164-
!node->data->simpleDescriptors().empty()) // already queried?
9165-
{
9166-
}
9167-
else if (m_steadyTimeRef - m_lastNwkAddrRequest < deCONZ::TimeSeconds{45})
9168-
{
9169-
}
9170-
else if (node->data->nodeDescriptor().manufacturerCode() == VENDOR_DDEL && node->data->address().nwk() == 0x0000)
9171-
{ // coordinator ghost nodes
9172-
}
9173-
#if 0
9174-
else if (node->data->lastDiscoveryTryMs(m_steadyTimeRef).val == 0 ||
9175-
ZombieDiscoveryEmptyInterval < node->data->lastDiscoveryTryMs(m_steadyTimeRef))
9176-
{
9177-
if (m_nodes.size() > 80 && !node->data->sourceRoutes().empty())
9178-
{
9179-
if (sendIeeeAddrRequest(node))
9180-
{
9181-
m_lastNwkAddrRequest = m_steadyTimeRef;
9182-
}
9183-
}
9184-
else if (sendNwkAddrRequest(node))
9185-
{
9186-
m_lastNwkAddrRequest = m_steadyTimeRef;
9187-
m_discoverIter++;
9188-
node->data->discoveryTimerReset(m_steadyTimeRef);
9189-
node->data->retryIncr(deCONZ::ReqNwkAddr);
9190-
return;
9191-
}
9192-
}
9193-
#endif
9194-
}
9195-
#endif // if 0
9196-
91979127
m_discoverIter++;
91989128
}
91999129
else
@@ -9370,19 +9300,27 @@ void zmController::deviceDiscoverTick()
93709300
{
93719301

93729302
}
9373-
else if (m_steadyTimeRef - m_lastNwkAddrRequest < deCONZ::TimeSeconds{15})
9303+
else if (m_steadyTimeRef - m_lastDiscoveryRequest < deCONZ::TimeSeconds{60})
93749304
{
93759305
// wait
93769306
m_deviceDiscoverQueue.push_back(addrPair);
93779307
}
9378-
//else if (node->data->isZombie() && sendNwkAddrRequest(node))
9379-
else if (ZDP_SendIeeeAddrRequest(this, addrPair.bAddr))
9308+
else if (node->data->recvErrors() >= 2 && deCONZ::TimeSeconds{60 * 5} < node->data->lastDiscoveryTryMs(m_steadyTimeRef) && ZDP_SendNwkAddrRequest(this, addrPair.bAddr))
9309+
{
9310+
m_lastDiscoveryRequest = m_steadyTimeRef;
9311+
node->data->discoveryTimerReset(m_steadyTimeRef);
9312+
return;
9313+
}
9314+
else if (node->data->recvErrors() < 2 && ZDP_SendIeeeAddrRequest(this, addrPair.bAddr))
93809315
{
9381-
m_lastNwkAddrRequest = m_steadyTimeRef;
9382-
node->data->retryIncr(deCONZ::ReqNwkAddr);
9316+
m_lastDiscoveryRequest = m_steadyTimeRef;
93839317
node->data->discoveryTimerReset(m_steadyTimeRef);
93849318
return;
93859319
}
9320+
else
9321+
{
9322+
m_deviceDiscoverQueue.push_back(addrPair);
9323+
}
93869324
}
93879325
}
93889326
}

src/zm_controller.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,6 @@ public slots:
315315
void fastPrope(uint64_t ext, uint16_t nwk, uint8_t macCapabilities);
316316
void wakeNode(NodeInfo *node);
317317
void deleteNode(NodeInfo *node, NodeRemoveMode finally);
318-
bool sendNwkAddrRequest(NodeInfo *node);
319-
bool sendIeeeAddrRequest(NodeInfo *node);
320318
bool sendMgtmLqiRequest(NodeInfo *info);
321319
bool sendMgtmRtgRequest(NodeInfo *node, uint8_t startIndex);
322320
bool sendNodeDescriptorRequest(NodeInfo *node);
@@ -356,7 +354,7 @@ public slots:
356354
bool m_showLqi = false;
357355
bool m_showNeighborLinks = true;
358356
QElapsedTimer m_fetchLqiTickMsCounter;
359-
deCONZ::SteadyTimeRef m_lastNwkAddrRequest;
357+
deCONZ::SteadyTimeRef m_lastDiscoveryRequest; // global NWK and IEEE requests
360358
deCONZ::SteadyTimeRef m_lastNodeAdded;
361359
deCONZ::SteadyTimeRef m_lastEndDeviceAnnounce;
362360
QElapsedTimer m_lastNodeDeleted;

0 commit comments

Comments
 (0)