11/*
2- * Copyright (c) 2013-2024 dresden elektronik ingenieurtechnik gmbh.
2+ * Copyright (c) 2013-2025 dresden elektronik ingenieurtechnik gmbh.
33 * All rights reserved.
44 *
55 * The software in this package is published under the terms of the BSD
99 */
1010
1111#include < deconz/dbg_trace.h>
12+ #include < deconz/u_assert.h>
1213#include " source_routing.h"
1314#include " zm_controller.h"
1415#include " zm_neighbor.h"
1516#include " zm_node.h"
1617
1718#define MAX_TRASH_ROUTE_TTL 16
1819#define MAX_TRASH_ROUTES 16
20+ #define MAX_ROUTE_ERRORS 6
21+ #define MAX_RECV_ERRORS 3
1922
2023static size_t MaxRecvErrors = 11 ;
2124
@@ -158,6 +161,11 @@ static bool updateSourceRoute(SourceRoute &route, const std::vector<NodeInfo> &n
158161 break ;
159162 }
160163
164+ if (node->data ->isZombie () || node->data ->recvErrors () >= MAX_RECV_ERRORS )
165+ {
166+ route.incrementErrors (); // slowly bring in error rate to accelerate route removal
167+ }
168+
161169 if (prevNode)
162170 {
163171 const zmNeighbor *neib = prevNode->data ->getNeighbor (hop);
@@ -171,7 +179,6 @@ static bool updateSourceRoute(SourceRoute &route, const std::vector<NodeInfo> &n
171179 route.m_hopLqi [i] = lqi;
172180 }
173181 }
174-
175182 }
176183
177184 prevNode = node;
@@ -294,29 +301,24 @@ static void calculateRouteForNode(const NodeInfo &node, const std::vector<NodeIn
294301 return ;
295302 }
296303
297- Q_ASSERT (routeIter < routes.size ());
304+ U_ASSERT (routeIter < routes.size ());
298305 auto &route = routes[routeIter];
299306
300- Q_ASSERT (maxHops > 2 );
307+ U_ASSERT (maxHops > 2 );
301308 DBG_Assert (!route.hops ().empty ());
302309 if (route.hops ().empty ())
303310 {
304311 return ;
305312 }
306313
307- if (route.hops ().size () >= static_cast <size_t >(maxHops))
308- {
309- return ;
310- }
311-
312314 if (route.hasHop (node1->address ()))
313315 {
314316 route.updateHopAddress (node1->address ());
315317
316318 if (route.hops ().back ().ext () == node1->address ().ext ())
317319 {
318320 bool updated = updateSourceRoute (route, nodes);
319- if (route.errors () > 10 && route.txOk () < route.errors ())
321+ if (route.errors () >= MAX_ROUTE_ERRORS && route.txOk () < route.errors ())
320322 {
321323 if (/* route.uuid().startsWith(QLatin1String("auto-")) &&*/ (tickCounter > (1000 / zmController::MainTickMs) * 60 ))
322324 {
@@ -349,6 +351,11 @@ static void calculateRouteForNode(const NodeInfo &node, const std::vector<NodeIn
349351 return ;
350352 }
351353
354+ if (route.hops ().size () >= static_cast <size_t >(maxHops))
355+ {
356+ return ;
357+ }
358+
352359 if (route.hops ().size () > 1 && (route.txOk () < 3 || route.errors () > route.txOk ()))
353360 {
354361 return ;
@@ -511,24 +518,6 @@ void SR_CalculateRouteForNode(const std::vector<NodeInfo> &nodes, std::vector<de
511518 return ;
512519 }
513520
514- int mightBeAlive = 2 ;
515- if (node.data ->isRouter () && (node.data ->isZombie () || node.data ->sourceRoutes ().empty () || !node.data ->sourceRoutes ().front ().isOperational ()))
516- {
517- mightBeAlive = 0 ;
518- for (size_t i = 0 ; i < nodes.size () && i < 128 && mightBeAlive < 2 ; i++)
519- {
520- if (nodes[i].data ->isEndDevice ())
521- continue ;
522-
523- zmNeighbor *neib = nodes[i].data ->getNeighbor (node.data ->address ());
524- if (neib && neib->m_lqi >= minLqi)
525- {
526- mightBeAlive++;
527- }
528- }
529- }
530-
531- if (mightBeAlive > 1 )
532521 {
533522 calculateRouteForNode (node, nodes, routeIter % routes.size (), routes, minLqi, maxHops, tickCounter);
534523 routeIter++;
@@ -543,10 +532,6 @@ void SR_CalculateRouteForNode(const std::vector<NodeInfo> &nodes, std::vector<de
543532 selectBestSourceRouteForNode (node, routes);
544533 }
545534 }
546- else
547- {
548- routeIter = routes.size (); // proceed with next
549- }
550535
551536 if (routeIter >= routes.size ())
552537 {
0 commit comments