Skip to content

rejoin drain rewiev #291

@Team-MT

Description

@Team-MT

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions