@@ -10,6 +10,8 @@ Zigbee_Core::Zigbee_Core() {
10
10
_zb_ep_list = esp_zb_ep_list_create ();
11
11
_primary_channel_mask = ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK;
12
12
_open_network = 0 ;
13
+ _scan_status = ZB_SCAN_FAILED;
14
+ _started = false ;
13
15
}
14
16
Zigbee_Core::~Zigbee_Core () {}
15
17
@@ -91,19 +93,22 @@ bool Zigbee_Core::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) {
91
93
esp_zb_init (zb_cfg);
92
94
93
95
// Register all Zigbee EPs in list
94
- log_d (" Register all Zigbee EPs in list" );
95
- err = esp_zb_device_register (_zb_ep_list);
96
- if (err != ESP_OK) {
97
- log_e (" Failed to register Zigbee EPs" );
98
- return false ;
99
- }
100
-
101
- // print the list of Zigbee EPs from ep_objects
102
- log_i (" List of registered Zigbee EPs:" );
103
- for (std::list<Zigbee_EP*>::iterator it = ep_objects.begin (); it != ep_objects.end (); ++it) {
104
- log_i (" Device type: %s, Endpoint: %d, Device ID: 0x%04x" , getDeviceTypeString ((*it)->_device_id ), (*it)->_endpoint , (*it)->_device_id );
96
+ if (ep_objects.empty ()) {
97
+ log_w (" No Zigbee EPs to register" );
98
+ } else {
99
+ log_d (" Register all Zigbee EPs in list" );
100
+ err = esp_zb_device_register (_zb_ep_list);
101
+ if (err != ESP_OK) {
102
+ log_e (" Failed to register Zigbee EPs" );
103
+ return false ;
104
+ }
105
+
106
+ // print the list of Zigbee EPs from ep_objects
107
+ log_i (" List of registered Zigbee EPs:" );
108
+ for (std::list<Zigbee_EP*>::iterator it = ep_objects.begin (); it != ep_objects.end (); ++it) {
109
+ log_i (" Device type: %s, Endpoint: %d, Device ID: 0x%04x" , getDeviceTypeString ((*it)->_device_id ), (*it)->_endpoint , (*it)->_device_id );
110
+ }
105
111
}
106
-
107
112
// Register Zigbee action handler
108
113
esp_zb_core_action_handler_register (zb_action_handler);
109
114
err = esp_zb_set_primary_network_channel_set (_primary_channel_mask);
@@ -159,7 +164,6 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
159
164
// coordinator variables
160
165
esp_zb_zdo_signal_device_annce_params_t *dev_annce_params = NULL ;
161
166
162
- log_d (" Zigbee role: %d" , Zigbee._role );
163
167
// main switch
164
168
switch (sig_type) {
165
169
case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP: // Common
@@ -183,8 +187,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
183
187
184
188
} else {
185
189
log_i (" Device rebooted" );
186
-
187
- // Implement opening network for joining after reboot if set
190
+ Zigbee._started = true ;
188
191
if ((zigbee_role_t )Zigbee._role == ZIGBEE_COORDINATOR && Zigbee._open_network > 0 ) {
189
192
log_i (" Openning network for joining for %d seconds" , Zigbee._open_network );
190
193
esp_zb_bdb_open_network (Zigbee._open_network );
@@ -213,6 +216,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
213
216
}
214
217
break ;
215
218
case ESP_ZB_BDB_SIGNAL_STEERING: // Router and End Device
219
+ Zigbee._started = true ;
216
220
if ((zigbee_role_t )Zigbee._role == ZIGBEE_COORDINATOR) {
217
221
if (err_status == ESP_OK) {
218
222
log_i (" Network steering started" );
@@ -283,18 +287,56 @@ void Zigbee_Core::factoryReset() {
283
287
esp_zb_factory_reset ();
284
288
}
285
289
290
+ bool Zigbee_Core::isStarted () {
291
+ return _started;
292
+ }
293
+
294
+ void Zigbee_Core::scanCompleteCallback (esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor){
295
+ log_v (" Zigbee network scan complete" );
296
+ if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
297
+ log_v (" Found %d networks" , count);
298
+ // print Zigbee networks
299
+ for (int i = 0 ; i < count; i++) {
300
+ log_v (" Network %d: PAN ID: 0x%04hx, Permit Joining: %s, Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, Channel: %d, Router Capacity: %s, End Device Capacity: %s" ,
301
+ i, nwk_descriptor[i].short_pan_id , nwk_descriptor[i].permit_joining ? " Yes" : " No" , nwk_descriptor[i].extended_pan_id [7 ], nwk_descriptor[i].extended_pan_id [6 ], nwk_descriptor[i].extended_pan_id [5 ], nwk_descriptor[i].extended_pan_id [4 ], nwk_descriptor[i].extended_pan_id [3 ], nwk_descriptor[i].extended_pan_id [2 ], nwk_descriptor[i].extended_pan_id [1 ], nwk_descriptor[i].extended_pan_id [0 ], nwk_descriptor[i].logic_channel , nwk_descriptor[i].router_capacity ? " Yes" : " No" , nwk_descriptor[i].end_device_capacity ? " Yes" : " No" );
302
+ }
303
+ // save scan result and update scan status
304
+ // copy network descriptor to _scan_result to keep the data after the callback
305
+ Zigbee._scan_result = (esp_zb_network_descriptor_t *)malloc (count * sizeof (esp_zb_network_descriptor_t ));
306
+ memcpy (Zigbee._scan_result , nwk_descriptor, count * sizeof (esp_zb_network_descriptor_t ));
307
+ Zigbee._scan_status = count;
308
+ } else {
309
+ log_e (" Failed to scan Zigbee network (status: 0x%x)" , zdo_status);
310
+ Zigbee._scan_status = ZB_SCAN_FAILED;
311
+ Zigbee._scan_result = nullptr ;
312
+ }
313
+ }
314
+
315
+ void Zigbee_Core::scanNetworks (u_int32_t channel_mask, u_int8_t scan_duration) {
316
+ if (!_started) {
317
+ log_e (" Zigbee stack is not started, cannot scan networks" );
318
+ return ;
319
+ }
320
+ log_v (" Scanning Zigbee networks" );
321
+ esp_zb_zdo_active_scan_request (channel_mask, scan_duration, scanCompleteCallback);
322
+ _scan_status = ZB_SCAN_RUNNING;
323
+ }
324
+
325
+ int16_t Zigbee_Core::scanComplete (){
326
+ return _scan_status;
327
+ }
328
+
329
+ zigbee_scan_result_t * Zigbee_Core::getScanResult () {
330
+ return _scan_result;
331
+ }
286
332
287
- // TODO: Implement scanning network
288
- // /**
289
- // * @brief Active scan available network.
290
- // *
291
- // * Network discovery service for scanning available network
292
- // *
293
- // * @param[in] channel_mask Valid channel mask is from 0x00000800 (only channel 11) to 0x07FFF800 (all channels from 11 to 26)
294
- // * @param[in] scan_duration Time to spend scanning each channel
295
- // * @param[in] user_cb A user callback to get the active scan result please refer to esp_zb_zdo_scan_complete_callback_t
296
- // */
297
- // void esp_zb_zdo_active_scan_request(uint32_t channel_mask, uint8_t scan_duration, esp_zb_zdo_scan_complete_callback_t user_cb);
333
+ void Zigbee_Core::scanDelete () {
334
+ if (_scan_result != nullptr ) {
335
+ free (_scan_result);
336
+ _scan_result = nullptr ;
337
+ }
338
+ _scan_status = ZB_SCAN_FAILED;
339
+ }
298
340
299
341
// NOTE: Binding functions to not forget
300
342
// void esp_zb_zdo_device_bind_req(esp_zb_zdo_bind_req_param_t *cmd_req, esp_zb_zdo_bind_callback_t user_cb, void *user_ctx)
0 commit comments