Title: Critical bugs in rejoin logic causing unnecessary battery drain and non-optimal hub search
Description:
While reviewing the rejoin and steering logic in src/zb_appCb.c, I found two serious bugs and a few minor discrepancies that together cause excessive radio activity and unpredictability in network reconnection. These issues directly increase battery consumption and make the device less reliable in finding/keeping the coordinator.
1. Inverted timer cancel condition in zb_bdbInitCb (major)
File: src/zb_appCb.c
Block: #if REJOIN_FAILURE_TIMER inside zb_bdbInitCb
if(joinedNetwork) {
zb_rejoinReqWithBackOff(zb_apsChannelMaskGet(), g_bdbAttrs.scanDuration);
if(!g_sensorAppCtx.timerRejoinBackoffEvt){ // ❌ wrong: should be without "!"
TL_ZB_TIMER_CANCEL(&g_sensorAppCtx.timerRejoinBackoffEvt);
}
}
Problem:
The condition if(!evt) cancels the timer only when the timer does NOT exist. When the device is already on a network but receives BDB_INIT_STATUS_FAILURE, the existing rejoin-backoff timer is never cancelled. As a result, periodic rejoin attempts keep firing even while connected, wasting power and generating unnecessary radio traffic.
fix:
Remove the negation:
if(g_sensorAppCtx.timerRejoinBackoffEvt) {
TL_ZB_TIMER_CANCEL(&g_sensorAppCtx.timerRejoinBackoffEvt);
}
Missing return in sensorDevice_rejoinBackoff (major)
File: src/zb_appCb.c
Function: sensorDevice_rejoinBackoff – #else branch (when REJOIN_FAILURE_TIMER is not active)
#else
static bool rejoinMode = REJOIN_SECURITY;
...
rejoinMode = !rejoinMode;
// ❌ missing return 0;
#endif
}
Problem:
The function is declared as static s32 sensorDevice_rejoinBackoff(void *arg), but the #else path lacks a final return statement. This is undefined behavior. The return value of a timer callback usually controls whether the timer is re-scheduled (0 = restart, -1 = stop). A garbage return value can either stop the rejoin backoff entirely (device never recovers) or restart it with an unexpected interval, leading to erratic reconnection attempts and increased power drain.
Fix:
Add return 0; before the #endif:
rejoinMode = !rejoinMode;
return 0;
#endif
Impact summary
- Battery drain: The device performs unnecessary rejoin attempts even when already connected.
- Unreliable reconnection: The broken return value can break the backoff mechanism.
- Network noise: Extra Zigbee traffic may affect coordinator performance.
Title: Critical bugs in rejoin logic causing unnecessary battery drain and non-optimal hub search
Description:
While reviewing the rejoin and steering logic in
src/zb_appCb.c, I found two serious bugs and a few minor discrepancies that together cause excessive radio activity and unpredictability in network reconnection. These issues directly increase battery consumption and make the device less reliable in finding/keeping the coordinator.1. Inverted timer cancel condition in
zb_bdbInitCb(major)File:
src/zb_appCb.cBlock:
#if REJOIN_FAILURE_TIMERinsidezb_bdbInitCbProblem:
The condition
if(!evt)cancels the timer only when the timer does NOT exist. When the device is already on a network but receivesBDB_INIT_STATUS_FAILURE, the existing rejoin-backoff timer is never cancelled. As a result, periodic rejoin attempts keep firing even while connected, wasting power and generating unnecessary radio traffic.fix:
Remove the negation:
Missing
returninsensorDevice_rejoinBackoff(major)File:
src/zb_appCb.cFunction:
sensorDevice_rejoinBackoff–#elsebranch (whenREJOIN_FAILURE_TIMERis not active)Problem:
The function is declared as
static s32 sensorDevice_rejoinBackoff(void *arg), but the#elsepath lacks a finalreturnstatement. This is undefined behavior. The return value of a timer callback usually controls whether the timer is re-scheduled (0= restart,-1= stop). A garbage return value can either stop the rejoin backoff entirely (device never recovers) or restart it with an unexpected interval, leading to erratic reconnection attempts and increased power drain.Fix:
Add
return 0;before the#endif:Impact summary