6
6
#include " ZigbeeHandlers.cpp"
7
7
#include " Arduino.h"
8
8
9
- #define ZB_INIT_TIMEOUT 30000 // 30 seconds
9
+ #ifdef __cplusplus
10
+ extern " C" {
11
+ #endif
12
+ #include " zboss_api.h"
13
+ extern zb_ret_t zb_nvram_write_dataset (zb_nvram_dataset_types_t t); // rejoin scanning workaround
14
+ extern void zb_set_ed_node_descriptor (bool power_src, bool rx_on_when_idle, bool alloc_addr); // sleepy device power mode workaround
15
+ #ifdef __cplusplus
16
+ }
17
+ #endif
10
18
11
- extern " C" void zb_set_ed_node_descriptor (bool power_src, bool rx_on_when_idle, bool alloc_addr);
12
19
static bool edBatteryPowered = false ;
13
20
14
21
ZigbeeCore::ZigbeeCore () {
@@ -18,6 +25,7 @@ ZigbeeCore::ZigbeeCore() {
18
25
_primary_channel_mask = ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK;
19
26
_open_network = 0 ;
20
27
_scan_status = ZB_SCAN_FAILED;
28
+ _begin_timeout = ZB_BEGIN_TIMEOUT_DEFAULT;
21
29
_started = false ;
22
30
_connected = false ;
23
31
_scan_duration = 3 ; // default scan duration
@@ -39,8 +47,11 @@ bool ZigbeeCore::begin(esp_zb_cfg_t *role_cfg, bool erase_nvs) {
39
47
return false ;
40
48
}
41
49
_role = (zigbee_role_t )role_cfg->esp_zb_role ;
42
- if (xSemaphoreTake (lock, ZB_INIT_TIMEOUT) != pdTRUE) {
43
- log_e (" ZigbeeCore begin timeout" );
50
+ if (xSemaphoreTake (lock, _begin_timeout) != pdTRUE) {
51
+ log_e (" ZigbeeCore begin failed or timeout" );
52
+ if (_role != ZIGBEE_COORDINATOR) { // Only End Device and Router can rejoin
53
+ resetNVRAMChannelMask ();
54
+ }
44
55
}
45
56
return started ();
46
57
}
@@ -71,8 +82,11 @@ bool ZigbeeCore::begin(zigbee_role_t role, bool erase_nvs) {
71
82
}
72
83
default : log_e (" Invalid Zigbee Role" ); return false ;
73
84
}
74
- if (!status || xSemaphoreTake (lock, ZB_INIT_TIMEOUT ) != pdTRUE) {
85
+ if (!status || xSemaphoreTake (lock, _begin_timeout ) != pdTRUE) {
75
86
log_e (" ZigbeeCore begin failed or timeout" );
87
+ if (_role != ZIGBEE_COORDINATOR) { // Only End Device and Router can rejoin
88
+ resetNVRAMChannelMask ();
89
+ }
76
90
}
77
91
return started ();
78
92
}
@@ -220,6 +234,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
220
234
switch (sig_type) {
221
235
case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP: // Common
222
236
log_i (" Zigbee stack initialized" );
237
+ log_d (" Zigbee channel mask: 0x%08x" , esp_zb_get_channel_mask ());
223
238
esp_zb_bdb_start_top_level_commissioning (ESP_ZB_BDB_MODE_INITIALIZATION);
224
239
break ;
225
240
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START: // Common
@@ -245,6 +260,8 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
245
260
log_i (" Opening network for joining for %d seconds" , Zigbee._open_network );
246
261
esp_zb_bdb_open_network (Zigbee._open_network );
247
262
} else {
263
+ // Save the channel mask to NVRAM in case of reboot which may be on a different channel after a change in the network
264
+ Zigbee.setNVRAMChannelMask (1 << esp_zb_get_current_channel ());
248
265
Zigbee._connected = true ;
249
266
}
250
267
Zigbee.searchBindings ();
@@ -289,6 +306,8 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
289
306
extended_pan_id[0 ], esp_zb_get_pan_id (), esp_zb_get_current_channel (), esp_zb_get_short_address ()
290
307
);
291
308
Zigbee._connected = true ;
309
+ // Set channel mask and write to NVRAM, so that the device will re-join the network faster after reboot (scan only on the current channel)
310
+ Zigbee.setNVRAMChannelMask (1 << esp_zb_get_current_channel ());
292
311
} else {
293
312
log_i (" Network steering was not successful (status: %s)" , esp_err_to_name (err_status));
294
313
esp_zb_scheduler_alarm ((esp_zb_callback_t )bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_STEERING, 1000 );
@@ -483,6 +502,20 @@ void ZigbeeCore::searchBindings() {
483
502
esp_zb_zdo_binding_table_req (mb_req, bindingTableCb, (void *)mb_req);
484
503
}
485
504
505
+ void ZigbeeCore::resetNVRAMChannelMask () {
506
+ _primary_channel_mask = ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK;
507
+ esp_zb_set_channel_mask (_primary_channel_mask);
508
+ zb_nvram_write_dataset (ZB_NVRAM_COMMON_DATA);
509
+ log_v (" Channel mask reset to all channels" );
510
+ }
511
+
512
+ void ZigbeeCore::setNVRAMChannelMask (uint32_t mask) {
513
+ _primary_channel_mask = mask;
514
+ esp_zb_set_channel_mask (_primary_channel_mask);
515
+ zb_nvram_write_dataset (ZB_NVRAM_COMMON_DATA);
516
+ log_v (" Channel mask set to 0x%08x" , mask);
517
+ }
518
+
486
519
// Function to convert enum value to string
487
520
const char *ZigbeeCore::getDeviceTypeString (esp_zb_ha_standard_devices_t deviceId) {
488
521
switch (deviceId) {
0 commit comments