Skip to content

Commit

Permalink
Merge branch 'backport/upgrade-zigbee-examples-v5.3' into 'release/v5.3'
Browse files Browse the repository at this point in the history
feat(zigbee): Upgrade the Zigbee lib to v1.6 for Zigbee examples(Backport v5.3)

See merge request espressif/esp-idf!34715
  • Loading branch information
Jiang Jiang Jian committed Nov 8, 2024
2 parents 780f99b + ca41ac9 commit 7e712b6
Show file tree
Hide file tree
Showing 26 changed files with 352 additions and 308 deletions.
11 changes: 3 additions & 8 deletions examples/zigbee/.build-test-rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,15 @@

examples/zigbee/esp_zigbee_gateway:
enable:
- if: SOC_WIFI_SUPPORTED == 1 and IDF_TARGET != "esp32c2"
reason: not supported esp32c2
<<: *zigbee_dependencies

examples/zigbee/esp_zigbee_rcp:
enable:
- if: SOC_IEEE802154_SUPPORTED == 1
- if: SOC_WIFI_SUPPORTED == 1 and IDF_TARGET not in ["esp32c2", "esp32c61"]
reason: not supported esp32c2 and esp32c61
<<: *zigbee_dependencies

examples/zigbee/light_sample:
enable:
- if: SOC_IEEE802154_SUPPORTED == 1
disable_test:
- if: IDF_TARGET == "esp32c6"
- if: IDF_TARGET != "esp32h2"
temporary: true
reason: only test on esp32h2
<<: *zigbee_dependencies
51 changes: 51 additions & 0 deletions examples/zigbee/common/zcl_utility/include/zcl_utility.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: LicenseRef-Included
*
* Zigbee Common
*
* This example code is in the Public Domain (or CC0 licensed, at your option.)
*
* 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.
*/

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include "esp_err.h"
#include "esp_check.h"
#include "esp_zigbee_core.h"

/*! Maximum length of ManufacturerName string field */
#define ESP_ZB_ZCL_CLUSTER_ID_BASIC_MANUFACTURER_NAME_MAX_LEN 32

/*! Maximum length of ModelIdentifier string field */
#define ESP_ZB_ZCL_CLUSTER_ID_BASIC_MODEL_IDENTIFIER_MAX_LEN 32

/** optional basic manufacturer information */
typedef struct zcl_basic_manufacturer_info_s {
char *manufacturer_name;
char *model_identifier;
} zcl_basic_manufacturer_info_t;

/**
* @brief Adds manufacturer information to the ZCL basic cluster of endpoint
*
* @param[in] ep_list The pointer to the endpoint list with @p endpoint_id
* @param[in] endpoint_id The endpoint identifier indicating where the ZCL basic cluster resides
* @param[in] info The pointer to the basic manufacturer information
* @return
* - ESP_OK: On success
* - ESP_ERR_INVALID_ARG: Invalid argument
*/
esp_err_t esp_zcl_utility_add_ep_basic_manufacturer_info(esp_zb_ep_list_t *ep_list, uint8_t endpoint_id, zcl_basic_manufacturer_info_t *info);

#ifdef __cplusplus
} // extern "C"
#endif
37 changes: 37 additions & 0 deletions examples/zigbee/common/zcl_utility/src/zcl_utility.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: LicenseRef-Included
*
* Zigbee Common
*
* This example code is in the Public Domain (or CC0 licensed, at your option.)
*
* 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.
*/
#include "esp_check.h"
#include "stdio.h"
#include "string.h"
#include "zcl_utility.h"
#include <stdint.h>

static const char *TAG = "ZCL_UTILITY";

esp_err_t esp_zcl_utility_add_ep_basic_manufacturer_info(esp_zb_ep_list_t *ep_list, uint8_t endpoint_id, zcl_basic_manufacturer_info_t *info)
{
esp_err_t ret = ESP_OK;
esp_zb_cluster_list_t *cluster_list = NULL;
esp_zb_attribute_list_t *basic_cluster = NULL;

cluster_list = esp_zb_ep_list_get_ep(ep_list, endpoint_id);
ESP_RETURN_ON_FALSE(cluster_list, ESP_ERR_INVALID_ARG, TAG, "Failed to find endpoint id: %d in list: %p", endpoint_id, ep_list);
basic_cluster = esp_zb_cluster_list_get_cluster(cluster_list, ESP_ZB_ZCL_CLUSTER_ID_BASIC, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
ESP_RETURN_ON_FALSE(basic_cluster, ESP_ERR_INVALID_ARG, TAG, "Failed to find basic cluster in endpoint: %d", endpoint_id);
ESP_RETURN_ON_FALSE((info && info->manufacturer_name), ESP_ERR_INVALID_ARG, TAG, "Invalid manufacturer name");
ESP_ERROR_CHECK(esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, info->manufacturer_name));
ESP_RETURN_ON_FALSE((info && info->model_identifier), ESP_ERR_INVALID_ARG, TAG, "Invalid model identifier");
ESP_ERROR_CHECK(esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, info->model_identifier));
return ret;
}
85 changes: 75 additions & 10 deletions examples/zigbee/esp_zigbee_gateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The ESP Zigbee SDK provides more examples and tools for productization:

By default, two SoCs are required to run this example:
* An ESP32 series Wi-Fi SoC (ESP32, ESP32-C, ESP32-S, etc) loaded with this esp_zigbee_gateway example.
* An ESP32-H2 802.15.4 SoC loaded with [esp_zigbee_rcp](../esp_zigbee_rcp) example
* An ESP32-H2 802.15.4 SoC loaded with [ot_rcp](../../openthread/ot_rcp/) example

Connect the two SoCs via UART, below is an example setup with ESP32-DevKitC and ESP32-H2-DevKitC:
![Zigbee_gateway](../../openthread/ot_br/image/thread-border-router-esp32-esp32h2.jpg)
Expand All @@ -28,6 +28,10 @@ ESP32 pin | ESP32-H2 pin

The example could also run on a single SoC which supports both Wi-Fi and Zigbee (e.g., ESP32-C6), but since there is only one RF path in ESP32-C6, which means Wi-Fi and Zigbee can't receive simultaneously, it has a significant impact on performance. Hence the two SoCs solution is recommended.

## Configure the RCP

The `OPENTHREAD_NCP_VENDOR_HOOK` of `ot_rcp` should be selected via menuconfig when the [ot_rcp](../../openthread/ot_rcp/) example is built. Then use `idf.py -p PORT erase-flash` to flash the RCP firmware to ESP32-H2-DevKitC.

## Configure the project

Before project configuration and build, make sure to set the correct chip target using `idf.py set-target <chip_name>`.
Expand All @@ -50,19 +54,80 @@ As you run the example, you will see the following log:

esp_zigbee_gateway:
```
I (660) ESP_ZB_GATEWAY: status: -1
I (670) ESP_ZB_GATEWAY: Zigbee stack initialized
I (680) ESP_ZB_GATEWAY: Zigbee rcp device booted
I (1280) ESP_ZB_GATEWAY: Start network formation
I (3060) ESP_ZB_GATEWAY: Formed network successfully (Extended PAN ID: f9:54:2d:01:a0:03:f7:84, PAN ID: 0x8651, Channel:13, Short Address: 0x0000)
I (4060) ESP_ZB_GATEWAY: status: 0
I (4400) ESP_ZB_GATEWAY: Network steering started
I (499) main_task: Calling app_main()
I (519) ESP_RADIO_SPINEL: spinel UART interface initialization completed
I (519) ESP_RADIO_SPINEL: Spinel UART interface has been successfully enabled
I (519) ZB_ESP_SPINEL: Spinel UART interface enable successfully
I (529) main_task: Returned from app_main()
I(529) OPENTHREAD:[I] P-RadioSpinel-: RCP reset: RESET_POWER_ON
I(539) OPENTHREAD:[I] P-RadioSpinel-: Software reset RCP successfully
I (569) ZB_ESP_SPINEL: Radio spinel workflow register successfully
I (769) ESP_ZB_GATEWAY: Production configuration is ready
W (769) ESP_ZB_GATEWAY: Production configuration is not present
I (769) example_connect: Start example_connect.
I (779) pp: pp rom version: e7ae62f
I (779) net80211: net80211 rom version: e7ae62f
I (799) wifi:wifi driver task: 3fca80d8, prio:23, stack:6656, core=0
I (799) wifi:wifi firmware version: 3ce09e5
I (799) wifi:wifi certification version: v7.0
I (799) wifi:config NVS flash: enabled
I (799) wifi:config nano formatting: disabled
I (809) wifi:Init data frame dynamic rx buffer num: 32
I (809) wifi:Init static rx mgmt buffer num: 5
I (819) wifi:Init management short buffer num: 32
I (819) wifi:Init dynamic tx buffer num: 32
I (819) wifi:Init static tx FG buffer num: 2
I (829) wifi:Init static rx buffer size: 1600
I (829) wifi:Init static rx buffer num: 10
I (839) wifi:Init dynamic rx buffer num: 32
I (839) wifi_init: rx ba win: 6
I (839) wifi_init: tcpip mbox: 32
I (849) wifi_init: udp mbox: 6
I (849) wifi_init: tcp mbox: 6
I (849) wifi_init: tcp tx win: 5760
I (859) wifi_init: tcp rx win: 5760
I (859) wifi_init: tcp mss: 1440
I (869) wifi_init: WiFi IRAM OP enabled
I (869) wifi_init: WiFi RX IRAM OP enabled
I (879) phy_init: phy_version 670,b7bc9b9,Apr 30 2024,10:54:13
W (879) phy_init: failed to load RF calibration data (0x1102), falling back to full calibration
I (989) wifi:mode : sta (f4:12:fa:41:a7:f4)
I (989) wifi:enable tsf
I (999) example_connect: Connecting to esp-office-2.4G...
I (999) example_connect: Waiting for IP(s)
I (3409) wifi:new:<13,0>, old:<1,0>, ap:<255,255>, sta:<13,0>, prof:1
I (3649) wifi:state: init -> auth (b0)
I (3719) wifi:state: auth -> assoc (0)
I (3759) wifi:state: assoc -> run (10)
I (3769) wifi:connected with esp-office-2.4G, aid = 1, channel 13, BW20, bssid = 9c:3a:9a:04:18:92
I (3769) wifi:security: WPA2-PSK, phy: bgn, rssi: -42
I (3769) wifi:pm start, type: 1
I (3779) wifi:dp: 1, bi: 102400, li: 3, scale listen interval from 307200 us to 307200 us
I (3789) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 25000, mt_pti: 0, mt_time: 10000
I (3819) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (3849) wifi:<ba-add>idx:0 (ifx:0, 9c:3a:9a:04:18:92), tid:0, ssn:0, winSize:64
I (4799) esp_netif_handlers: example_netif_sta ip: 192.168.200.133, mask: 255.255.252.0, gw: 192.168.200.1
I (4799) example_connect: Got IPv4 event: Interface "example_netif_sta" address: 192.168.200.133
I (5509) example_connect: Got IPv6 event: Interface "example_netif_sta" address: fe80:0000:0000:0000:f612:faff:fe41:a7f4, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (5509) example_common: Connected to example_netif_sta
I (5519) example_common: - IPv4 address: 192.168.200.133,
I (5519) example_common: - IPv6 address: fe80:0000:0000:0000:f612:faff:fe41:a7f4, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (5529) wifi:Set ps type: 0, coexist: 0
I (5539) ESP_ZB_GATEWAY: Initialize Zigbee stack
I (5549) ESP_ZB_GATEWAY: Device started up in factory-reset mode
I (5549) ESP_ZB_GATEWAY: Start network formation
W (5729) ESP_ZB_GATEWAY: Network(0xb8e9) closed, devices joining not allowed.
I (5729) ESP_ZB_GATEWAY: Formed network successfully (Extended PAN ID: 60:55:f9:ff:fe:f7:73:e8, PAN ID: 0xb8e9, Channel:13, Short Address: 0x0000)
I (6339) ESP_ZB_GATEWAY: Network(0xb8e9) is open for 180 seconds
I (6339) ESP_ZB_GATEWAY: Network steering started
```

## Gateway Functions

* After Zigbee gateway starts up, it will read MAC ieee address and Zigbee stack version number from the Zigbee rcp and start working together with Zigbee rcp via UART communication to form a Zigbee network
* More Gateway functionalities supporting Wi-Fi interaction will come later
* When the device starts up, it will attempt to connect to a Wi-Fi network and then interface with the OT-RCP via UART to form a Zigbee network.
* For more Gateway functionalities, please refer to [matter zigbee bridge](https://github.com/espressif/esp-matter/tree/main/examples/bridge_apps/zigbee_bridge/) and [Rainmaker Zigbee Gateway](https://github.com/espressif/esp-rainmaker/tree/master/examples/zigbee_gateway) examples.

## Troubleshooting

Expand Down
65 changes: 38 additions & 27 deletions examples/zigbee/esp_zigbee_gateway/main/esp_zigbee_gateway.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
* SPDX-License-Identifier: LicenseRef-Included
*
* Zigbee Gateway Example
*
Expand All @@ -17,20 +17,17 @@
#include "freertos/task.h"
#include "driver/usb_serial_jtag.h"
#include "esp_coexist.h"
#include "esp_check.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_vfs_dev.h"
#include "esp_vfs_usb_serial_jtag.h"
#include "esp_vfs_eventfd.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "esp_zigbee_gateway.h"

#include "driver/uart_vfs.h"
#include "driver/usb_serial_jtag_vfs.h"

#if (!defined ZB_MACSPLIT_HOST && defined ZB_MACSPLIT_DEVICE)
#error Only Zigbee gateway host device should be defined
#endif
#include "zb_config_platform.h"

static const char *TAG = "ESP_ZB_GATEWAY";

Expand Down Expand Up @@ -61,7 +58,7 @@ esp_err_t esp_zb_gateway_console_init(void)

static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask)
{
ESP_ERROR_CHECK(esp_zb_bdb_start_top_level_commissioning(mode_mask));
ESP_RETURN_ON_FALSE(esp_zb_bdb_start_top_level_commissioning(mode_mask) == ESP_OK, , TAG, "Failed to start Zigbee bdb commissioning");
}

void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
Expand All @@ -70,18 +67,19 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
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;
esp_zb_zdo_signal_macsplit_dev_boot_params_t *rcp_version = NULL;

switch (sig_type) {
case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP:
ESP_LOGI(TAG, "Zigbee stack initialized");
#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");
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_INITIALIZATION);
break;
case ESP_ZB_MACSPLIT_DEVICE_BOOT:
ESP_LOGI(TAG, "Zigbee rcp device booted");
rcp_version = (esp_zb_zdo_signal_macsplit_dev_boot_params_t *)esp_zb_app_signal_get_params(p_sg_p);
ESP_LOGI(TAG, "Running RCP Version: %s", rcp_version->version_str);
break;
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
if (err_status == ESP_OK) {
Expand All @@ -90,6 +88,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
ESP_LOGI(TAG, "Start network formation");
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_FORMATION);
} else {
esp_zb_bdb_open_network(180);
ESP_LOGI(TAG, "Device rebooted");
}
} else {
Expand Down Expand Up @@ -128,6 +127,10 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
}
}
break;
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;
default:
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));
Expand All @@ -141,8 +144,25 @@ static void esp_zb_task(void *pvParameters)
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZC_CONFIG();
esp_zb_init(&zb_nwk_cfg);
esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
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);
ESP_ERROR_CHECK(esp_zb_start(false));
esp_zb_main_loop_iteration();
esp_zb_stack_main_loop();
vTaskDelete(NULL);
}

void app_main(void)
Expand All @@ -159,14 +179,5 @@ void app_main(void)
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
ESP_ERROR_CHECK(esp_zb_gateway_console_init());
#endif
#if CONFIG_EXAMPLE_CONNECT_WIFI
ESP_ERROR_CHECK(example_connect());
#if CONFIG_ESP_COEX_SW_COEXIST_ENABLE
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM));
esp_coex_wifi_i154_enable();
#else
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
#endif
#endif
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
xTaskCreate(esp_zb_task, "Zigbee_main", 8192, NULL, 5, NULL);
}
Loading

0 comments on commit 7e712b6

Please sign in to comment.