[zigbee] Improve network handling on esp32 (2/3) (#18008)

This commit is contained in:
luar123
2026-08-06 10:34:32 -04:00
committed by GitHub
parent 73689f8d8b
commit 3353e71f9a
2 changed files with 50 additions and 20 deletions
+43 -9
View File
@@ -36,6 +36,17 @@ uint8_t *get_zcl_string(const char *str, uint8_t max_size, bool use_max_size) {
return zcl_str;
}
void ZigbeeComponent::factory_reset() {
esp_zigbee_lock_acquire(portMAX_DELAY);
if (this->joined_) {
// send leave request and trigger EZB_ZDO_SIGNAL_LEAVE
ezb_bdb_reset_via_local_action();
} else {
esp_zigbee_factory_reset(); // triggers a reboot
}
esp_zigbee_lock_release();
}
void ZigbeeComponent::esp_zigbee_alarm_bdb_commissioning(ezb_bdb_comm_mode_mask_t mode) {
if (!esp_zigbee_lock_acquire(10 / portTICK_PERIOD_MS)) {
global_zigbee->set_timeout("zb_init", 10, [mode]() { ZigbeeComponent::esp_zigbee_alarm_bdb_commissioning(mode); });
@@ -53,7 +64,7 @@ bool ZigbeeComponent::app_signal_handler(const ezb_app_signal_t *app_signal) {
switch (signal_type) {
case EZB_ZDO_SIGNAL_SKIP_STARTUP:
ESP_LOGD(TAG, "Zigbee stack initialized");
global_zigbee->started = true;
global_zigbee->started_ = true;
ezb_bdb_start_top_level_commissioning(EZB_BDB_MODE_INITIALIZATION);
break;
case EZB_BDB_SIGNAL_DEVICE_FIRST_START:
@@ -62,12 +73,13 @@ bool ZigbeeComponent::app_signal_handler(const ezb_app_signal_t *app_signal) {
if (status == EZB_BDB_STATUS_SUCCESS) {
ESP_LOGD(TAG, "Device started up in %sfactory-reset mode", ezb_bdb_is_factory_new() ? "" : "non ");
if (ezb_bdb_is_factory_new()) {
global_zigbee->factory_new = true;
global_zigbee->factory_new_ = true;
ESP_LOGD(TAG, "Start network steering");
ezb_bdb_start_top_level_commissioning(EZB_BDB_MODE_NETWORK_STEERING);
} else {
ESP_LOGD(TAG, "Device rebooted");
global_zigbee->joined = true;
global_zigbee->joined_ = true;
global_zigbee->join_pending_ = true;
global_zigbee->enable_loop_soon_any_context();
}
} else {
@@ -85,7 +97,8 @@ bool ZigbeeComponent::app_signal_handler(const ezb_app_signal_t *app_signal) {
ezb_nwk_get_extended_panid(&extended_pan_id);
ESP_LOGD(TAG, "Joined network successfully: PAN ID(0x%04hx, EXT: 0x%llx), Channel(%d), Short Address(0x%04hx)",
ezb_nwk_get_panid(), extended_pan_id.u64, ezb_nwk_get_current_channel(), ezb_nwk_get_short_address());
global_zigbee->joined = true;
global_zigbee->joined_ = true;
global_zigbee->join_pending_ = true;
global_zigbee->enable_loop_soon_any_context();
} else {
ESP_LOGD(TAG, "Failed to join network with status(0x%02x)", status);
@@ -105,7 +118,29 @@ bool ZigbeeComponent::app_signal_handler(const ezb_app_signal_t *app_signal) {
const ezb_zdo_signal_leave_params_t *leave_params =
(const ezb_zdo_signal_leave_params_t *) ezb_app_signal_get_params(app_signal);
if (leave_params->leave_type == EZB_ZDO_LEAVE_TYPE_RESET) {
esp_zigbee_factory_reset();
esp_zigbee_factory_reset(); // triggers a reboot
}
global_zigbee->joined_ = false;
} break;
case EZB_NWK_SIGNAL_NETWORK_STATUS: {
const ezb_nwk_signal_network_status_params_t *network_status_params =
(const ezb_nwk_signal_network_status_params_t *) ezb_app_signal_get_params(app_signal);
if (network_status_params->status == EZB_NWK_NETWORK_STATUS_PARENT_LINK_FAILURE) {
global_zigbee->joined_ = false;
ESP_LOGW(TAG, "Parent link failure, attempting rejoin");
ezb_zdo_nwk_mgmt_leave_req_t leave_req = {
.dst_nwk_addr = ezb_nwk_get_short_address(),
.field =
{
.remove_children = false,
.rejoin = true,
},
};
// Send leave request to the network to rejoin
// triggers EZB_ZDO_SIGNAL_LEAVE signal first, then EZB_BDB_SIGNAL_DEVICE_REBOOT
ezb_zdo_nwk_mgmt_leave_req(&leave_req);
} else {
ESP_LOGD(TAG, "Zigbee APP Signal NETWORK_STATUS: 0x%02x", network_status_params->status);
}
} break;
default:
@@ -303,10 +338,9 @@ void ZigbeeComponent::setup() {
}
void ZigbeeComponent::loop() {
if (!this->join_reported_ && this->joined) {
this->join_reported_ = true;
this->join_cb_.call(this->factory_new);
this->factory_new = false;
if (this->join_pending_.exchange(false)) {
this->join_cb_.call(this->factory_new_);
this->factory_new_ = false;
}
this->disable_loop();
}
+7 -11
View File
@@ -54,11 +54,7 @@ class ZigbeeComponent final : public Component {
static bool app_signal_handler(const ezb_app_signal_t *app_signal);
static void esp_zigbee_alarm_bdb_commissioning(ezb_bdb_comm_mode_mask_t mode);
void factory_reset() {
esp_zigbee_lock_acquire(portMAX_DELAY);
esp_zigbee_factory_reset(); // triggers a reboot
esp_zigbee_lock_release();
}
void factory_reset();
template<typename F> void add_on_join_callback(F &&cb) { this->join_cb_.add(std::forward<F>(cb)); }
@@ -66,13 +62,10 @@ class ZigbeeComponent final : public Component {
// True after the Zigbee stack has been initialized and the device has started up. Is set before the stack started
// network commissioning or has joined a network and won't be reset until the device is rebooted.
bool is_started() { return this->started; }
bool is_started() { return this->started_; }
// True if the device has joined a network and is ready to send and receive messages.
bool is_joined() { return this->joined; }
std::atomic<bool> started = false;
std::atomic<bool> joined = false;
std::atomic<bool> factory_new = false;
bool is_joined() { return this->joined_; }
protected:
struct {
@@ -95,8 +88,11 @@ class ZigbeeComponent final : public Component {
// key tuple could be replaced by single 64 (48) bit int with bit fields for endpoint, cluster, role and attr_id
std::map<std::tuple<uint8_t, uint16_t, uint8_t, uint16_t>, ZigbeeAttribute *> attributes_;
ezb_af_device_desc_t dev_desc_;
bool join_reported_{false};
CallbackManager<void(bool)> join_cb_{};
std::atomic<bool> started_ = false;
std::atomic<bool> joined_ = false;
std::atomic<bool> join_pending_ = false;
std::atomic<bool> factory_new_ = false;
};
template<typename T>