2021-12-16 17:42:19 +08:00
/*
2024-01-25 14:03:10 +08:00
* SPDX - FileCopyrightText : 2021 - 2024 Espressif Systems ( Shanghai ) CO LTD
2021-12-16 17:42:19 +08:00
*
2024-08-07 10:47:05 +08:00
* SPDX - License - Identifier : LicenseRef - Included
2021-12-16 17:42:19 +08:00
*
2024-01-25 14:03:10 +08:00
* Zigbee Gateway Example
2021-12-16 17:42:19 +08:00
*
2024-01-25 14:03:10 +08:00
* This example code is in the Public Domain ( or CC0 licensed , at your option . )
2021-12-16 17:42:19 +08:00
*
2024-01-25 14:03:10 +08:00
* Unless required by applicable law or agreed to in writing , this
* software is distributed on an " AS IS " BASIS , WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND , either express or implied .
2021-12-16 17:42:19 +08:00
*/
2023-05-16 17:04:47 +08:00
# include <fcntl.h>
2023-08-29 15:58:44 +08:00
# include <string.h>
2021-12-16 17:42:19 +08:00
# include "freertos/FreeRTOS.h"
# include "freertos/task.h"
2023-08-29 15:58:44 +08:00
# include "driver/usb_serial_jtag.h"
2023-08-10 19:35:43 +08:00
# include "esp_coexist.h"
2024-08-07 10:47:05 +08:00
# include "esp_check.h"
2023-08-29 15:58:44 +08:00
# include "esp_log.h"
2023-04-04 12:06:01 +08:00
# include "esp_netif.h"
2024-08-07 10:47:05 +08:00
# include "esp_vfs_dev.h"
# include "esp_vfs_usb_serial_jtag.h"
2023-04-04 12:06:01 +08:00
# include "esp_vfs_eventfd.h"
# include "esp_wifi.h"
# include "nvs_flash.h"
# include "protocol_examples_common.h"
2021-12-16 17:42:19 +08:00
# include "esp_zigbee_gateway.h"
2024-08-07 10:47:05 +08:00
# include "zb_config_platform.h"
2021-12-16 17:42:19 +08:00
static const char * TAG = " ESP_ZB_GATEWAY " ;
2023-05-16 17:04:47 +08:00
/* Note: Please select the correct console output port based on the development board in menuconfig */
# if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
esp_err_t esp_zb_gateway_console_init ( void )
{
esp_err_t ret = ESP_OK ;
/* Disable buffering on stdin */
setvbuf ( stdin , NULL , _IONBF , 0 ) ;
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
2024-01-18 19:53:42 +08:00
usb_serial_jtag_vfs_set_rx_line_endings ( ESP_LINE_ENDINGS_CR ) ;
2023-05-16 17:04:47 +08:00
/* Move the caret to the beginning of the next line on '\n' */
2024-01-18 19:53:42 +08:00
usb_serial_jtag_vfs_set_tx_line_endings ( ESP_LINE_ENDINGS_CRLF ) ;
2023-05-16 17:04:47 +08:00
/* Enable non-blocking mode on stdin and stdout */
fcntl ( fileno ( stdout ) , F_SETFL , O_NONBLOCK ) ;
fcntl ( fileno ( stdin ) , F_SETFL , O_NONBLOCK ) ;
usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT ( ) ;
ret = usb_serial_jtag_driver_install ( & usb_serial_jtag_config ) ;
2024-01-18 19:53:42 +08:00
usb_serial_jtag_vfs_use_driver ( ) ;
uart_vfs_dev_register ( ) ;
2023-05-16 17:04:47 +08:00
return ret ;
}
# endif
2022-09-22 14:51:30 +08:00
static void bdb_start_top_level_commissioning_cb ( uint8_t mode_mask )
2021-12-16 17:42:19 +08:00
{
2024-08-07 10:47:05 +08:00
ESP_RETURN_ON_FALSE ( esp_zb_bdb_start_top_level_commissioning ( mode_mask ) = = ESP_OK , , TAG , " Failed to start Zigbee bdb commissioning " ) ;
2021-12-16 17:42:19 +08:00
}
2022-10-26 14:40:02 +08:00
void esp_zb_app_signal_handler ( esp_zb_app_signal_t * signal_struct )
2021-12-16 17:42:19 +08:00
{
2022-10-26 14:40:02 +08:00
uint32_t * p_sg_p = signal_struct - > p_app_signal ;
esp_err_t err_status = signal_struct - > esp_err_status ;
esp_zb_app_signal_type_t sig_type = * p_sg_p ;
esp_zb_zdo_signal_device_annce_params_t * dev_annce_params = NULL ;
2021-12-16 17:42:19 +08:00
2022-10-26 14:40:02 +08:00
switch ( sig_type ) {
case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP :
2024-08-07 10:47:05 +08:00
# if CONFIG_EXAMPLE_CONNECT_WIFI
# if CONFIG_ESP_COEX_SW_COEXIST_ENABLE
esp_coex_wifi_i154_enable ( ) ;
# endif /* CONFIG_ESP_COEX_SW_COEXIST_ENABLE */
ESP_RETURN_ON_FALSE ( example_connect ( ) = = ESP_OK , , TAG , " Failed to connect to Wi-Fi " ) ;
ESP_RETURN_ON_FALSE ( esp_wifi_set_ps ( WIFI_PS_MIN_MODEM ) = = ESP_OK , , TAG , " Failed to set Wi-Fi minimum modem power save type " ) ;
# endif /* CONFIG_EXAMPLE_CONNECT_WIFI */
ESP_LOGI ( TAG , " Initialize Zigbee stack " ) ;
2022-10-26 14:40:02 +08:00
esp_zb_bdb_start_top_level_commissioning ( ESP_ZB_BDB_MODE_INITIALIZATION ) ;
2021-12-16 17:42:19 +08:00
break ;
2022-10-26 14:40:02 +08:00
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START :
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT :
if ( err_status = = ESP_OK ) {
2024-01-25 14:03:10 +08:00
ESP_LOGI ( TAG , " Device started up in %s factory-reset mode " , esp_zb_bdb_is_factory_new ( ) ? " " : " non " ) ;
if ( esp_zb_bdb_is_factory_new ( ) ) {
ESP_LOGI ( TAG , " Start network formation " ) ;
esp_zb_bdb_start_top_level_commissioning ( ESP_ZB_BDB_MODE_NETWORK_FORMATION ) ;
} else {
2024-08-07 10:47:05 +08:00
esp_zb_bdb_open_network ( 180 ) ;
2024-01-25 14:03:10 +08:00
ESP_LOGI ( TAG , " Device rebooted " ) ;
}
2021-12-16 17:42:19 +08:00
} else {
2023-08-29 15:58:44 +08:00
ESP_LOGE ( TAG , " Failed to initialize Zigbee stack (status: %s) " , esp_err_to_name ( err_status ) ) ;
2021-12-16 17:42:19 +08:00
}
break ;
2022-10-26 14:40:02 +08:00
case ESP_ZB_BDB_SIGNAL_FORMATION :
if ( err_status = = ESP_OK ) {
esp_zb_ieee_addr_t ieee_address ;
2022-09-22 14:51:30 +08:00
esp_zb_get_long_address ( ieee_address ) ;
2024-01-25 14:03:10 +08:00
ESP_LOGI ( TAG , " Formed network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx) " ,
2021-12-16 17:42:19 +08:00
ieee_address [ 7 ] , ieee_address [ 6 ] , ieee_address [ 5 ] , ieee_address [ 4 ] ,
ieee_address [ 3 ] , ieee_address [ 2 ] , ieee_address [ 1 ] , ieee_address [ 0 ] ,
2024-01-25 14:03:10 +08:00
esp_zb_get_pan_id ( ) , esp_zb_get_current_channel ( ) , esp_zb_get_short_address ( ) ) ;
2022-10-26 14:40:02 +08:00
esp_zb_bdb_start_top_level_commissioning ( ESP_ZB_BDB_MODE_NETWORK_STEERING ) ;
2021-12-16 17:42:19 +08:00
} else {
2023-08-29 15:58:44 +08:00
ESP_LOGI ( TAG , " Restart network formation (status: %s) " , esp_err_to_name ( err_status ) ) ;
2022-10-26 14:40:02 +08:00
esp_zb_scheduler_alarm ( ( esp_zb_callback_t ) bdb_start_top_level_commissioning_cb , ESP_ZB_BDB_MODE_NETWORK_FORMATION , 1000 ) ;
2021-12-16 17:42:19 +08:00
}
break ;
2022-10-26 14:40:02 +08:00
case ESP_ZB_BDB_SIGNAL_STEERING :
if ( err_status = = ESP_OK ) {
2021-12-16 17:42:19 +08:00
ESP_LOGI ( TAG , " Network steering started " ) ;
}
break ;
2022-10-26 14:40:02 +08:00
case ESP_ZB_ZDO_SIGNAL_DEVICE_ANNCE :
dev_annce_params = ( esp_zb_zdo_signal_device_annce_params_t * ) esp_zb_app_signal_get_params ( p_sg_p ) ;
2021-12-16 17:42:19 +08:00
ESP_LOGI ( TAG , " New device commissioned or rejoined (short: 0x%04hx) " , dev_annce_params - > device_short_addr ) ;
2022-01-11 15:52:34 +08:00
break ;
2024-01-25 14:03:10 +08:00
case ESP_ZB_NWK_SIGNAL_PERMIT_JOIN_STATUS :
if ( err_status = = ESP_OK ) {
if ( * ( uint8_t * ) esp_zb_app_signal_get_params ( p_sg_p ) ) {
ESP_LOGI ( TAG , " Network(0x%04hx) is open for %d seconds " , esp_zb_get_pan_id ( ) , * ( uint8_t * ) esp_zb_app_signal_get_params ( p_sg_p ) ) ;
} else {
ESP_LOGW ( TAG , " Network(0x%04hx) closed, devices joining not allowed. " , esp_zb_get_pan_id ( ) ) ;
}
}
break ;
2024-08-07 10:47:05 +08:00
case ESP_ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY :
ESP_LOGI ( TAG , " Production configuration is %s " , err_status = = ESP_OK ? " ready " : " not present " ) ;
esp_zb_set_node_descriptor_manufacturer_code ( ESP_MANUFACTURER_CODE ) ;
break ;
2021-12-16 17:42:19 +08:00
default :
2023-08-29 15:58:44 +08:00
ESP_LOGI ( TAG , " ZDO signal: %s (0x%x), status: %s " , esp_zb_zdo_signal_to_string ( sig_type ) , sig_type ,
esp_err_to_name ( err_status ) ) ;
2021-12-16 17:42:19 +08:00
break ;
}
}
2022-09-22 14:51:30 +08:00
static void esp_zb_task ( void * pvParameters )
2021-12-16 17:42:19 +08:00
{
2024-01-25 14:03:10 +08:00
/* initialize Zigbee stack */
2022-09-22 14:51:30 +08:00
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZC_CONFIG ( ) ;
esp_zb_init ( & zb_nwk_cfg ) ;
2023-03-20 17:04:37 +08:00
esp_zb_set_primary_network_channel_set ( ESP_ZB_PRIMARY_CHANNEL_MASK ) ;
2024-08-07 10:47:05 +08:00
esp_zb_ep_list_t * ep_list = esp_zb_ep_list_create ( ) ;
esp_zb_cluster_list_t * cluster_list = esp_zb_zcl_cluster_list_create ( ) ;
esp_zb_endpoint_config_t endpoint_config = {
. endpoint = ESP_ZB_GATEWAY_ENDPOINT ,
. app_profile_id = ESP_ZB_AF_HA_PROFILE_ID ,
. app_device_id = ESP_ZB_HA_REMOTE_CONTROL_DEVICE_ID ,
. app_device_version = 0 ,
} ;
esp_zb_attribute_list_t * basic_cluser = esp_zb_basic_cluster_create ( NULL ) ;
esp_zb_basic_cluster_add_attr ( basic_cluser , ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID , ESP_MANUFACTURER_NAME ) ;
esp_zb_basic_cluster_add_attr ( basic_cluser , ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID , ESP_MODEL_IDENTIFIER ) ;
esp_zb_cluster_list_add_basic_cluster ( cluster_list , basic_cluser , ESP_ZB_ZCL_CLUSTER_SERVER_ROLE ) ;
esp_zb_cluster_list_add_identify_cluster ( cluster_list , esp_zb_identify_cluster_create ( NULL ) , ESP_ZB_ZCL_CLUSTER_SERVER_ROLE ) ;
esp_zb_ep_list_add_gateway_ep ( ep_list , cluster_list , endpoint_config ) ;
esp_zb_device_register ( ep_list ) ;
2022-09-22 14:51:30 +08:00
ESP_ERROR_CHECK ( esp_zb_start ( false ) ) ;
2024-08-07 10:47:05 +08:00
esp_zb_stack_main_loop ( ) ;
vTaskDelete ( NULL ) ;
2021-12-16 17:42:19 +08:00
}
2022-01-11 15:52:34 +08:00
void app_main ( void )
2021-12-16 17:42:19 +08:00
{
2022-09-22 14:51:30 +08:00
esp_zb_platform_config_t config = {
. radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG ( ) ,
. host_config = ESP_ZB_DEFAULT_HOST_CONFIG ( ) ,
2021-12-16 17:42:19 +08:00
} ;
2024-01-25 14:03:10 +08:00
2022-09-22 14:51:30 +08:00
ESP_ERROR_CHECK ( esp_zb_platform_config ( & config ) ) ;
2023-04-04 12:06:01 +08:00
ESP_ERROR_CHECK ( nvs_flash_init ( ) ) ;
ESP_ERROR_CHECK ( esp_netif_init ( ) ) ;
ESP_ERROR_CHECK ( esp_event_loop_create_default ( ) ) ;
2023-05-16 17:04:47 +08:00
# if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
ESP_ERROR_CHECK ( esp_zb_gateway_console_init ( ) ) ;
# endif
2024-08-07 10:47:05 +08:00
xTaskCreate ( esp_zb_task , " Zigbee_main " , 8192 , NULL , 5 , NULL ) ;
2021-12-16 17:42:19 +08:00
}