espressif / esp-zigbee-sdk

Espressif Zigbee SDK
Apache License 2.0
178 stars 31 forks source link

Custom cluster is not being created (TZ-1069) #406

Closed aerosh closed 3 months ago

aerosh commented 3 months ago

Answers checklist.

IDF version.

v5.3

esp-zigbee-lib version.

1.4.1

esp-zboss-lib version.

1.4.1

Espressif SoC revision.

ESP32-H2

What is the expected behavior?

I (434) DEMO: Cluster ID: 0xFFF2 I (434) DEMO: Attribute Count: 1

What is the actual behavior?

I (434) DEMO: Cluster ID: 0x0000 I (434) DEMO: Attribute Count: 0

Steps to reproduce.

#define TVOC_CUSTOM_CLUSTER              0xFFF2 

esp_zb_attribute_list_t *custom_tvoc_attributes_list = esp_zb_zcl_attr_list_create(TVOC_CUSTOM_CLUSTER);
esp_zb_custom_cluster_add_custom_attr(custom_tvoc_attributes_list, 0, ESP_ZB_ZCL_ATTR_TYPE_U16, ESP_ZB_ZCL_ATTR_MANUF_SPEC | ESP_ZB_ZCL_ATTR_ACCESS_READ_WRITE | ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, &undefined_value);
esp_zb_zcl_cluster_t *custom_tvoc_cluster = (esp_zb_zcl_cluster_t *)custom_tvoc_attributes_list;
ESP_LOGI(TAG, "Cluster ID: 0x%04X", custom_tvoc_cluster->cluster_id);
ESP_LOGI(TAG, "Attribute Count: %d", custom_tvoc_cluster->attr_count);

More Information.

I am trying to create a custom cluster in the following way:

#define TVOC_CUSTOM_CLUSTER              0xFFF2
uint16_t undefined_value;
undefined_value = 0;
esp_zb_attribute_list_t *custom_tvoc_attributes_list = esp_zb_zcl_attr_list_create(TVOC_CUSTOM_CLUSTER);
esp_zb_custom_cluster_add_custom_attr(custom_tvoc_attributes_list, 0, ESP_ZB_ZCL_ATTR_TYPE_U16, ESP_ZB_ZCL_ATTR_MANUF_SPEC | ESP_ZB_ZCL_ATTR_ACCESS_READ_WRITE | ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, &undefined_value);
/* For debug */
esp_zb_zcl_cluster_t *custom_tvoc_cluster = (esp_zb_zcl_cluster_t *)custom_tvoc_attributes_list;
ESP_LOGI(TAG, "Cluster ID: 0x%04X", custom_tvoc_cluster->cluster_id);
ESP_LOGI(TAG, "Attribute Count: %d", custom_tvoc_cluster->attr_count);
/* End debug */
esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_custom_cluster(esp_zb_cluster_list, custom_tvoc_attributes_list, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
// ------------------------------ Create endpoint list ------------------------------
esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
esp_zb_endpoint_config_t endpoint_config = {
    .endpoint = SENSOR_ENDPOINT,
    .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
    .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, 
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list, endpoint_config);
// ------------------------------ Register Device ------------------------------
esp_zb_device_register(esp_zb_ep_list);
esp_zb_core_action_handler_register(zb_action_handler);
esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
ESP_ERROR_CHECK(esp_zb_start(false));
esp_zb_main_loop_iteration();

Then I try to pass the value in the following way:

void reportAttribute(uint8_t endpoint, uint16_t clusterID, uint16_t attributeID, void *value, uint8_t value_length)
{
    esp_zb_zcl_report_attr_cmd_t cmd = {
        .zcl_basic_cmd = {
            .dst_addr_u.addr_short = 0x0000,
            .dst_endpoint = endpoint,
            .src_endpoint = endpoint,
        },
        .address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT,
        .clusterID = clusterID,
        .attributeID = attributeID,
        .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
    };
    esp_zb_zcl_attr_t *value_r = esp_zb_zcl_get_attribute(endpoint, clusterID, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, attributeID);

    if (value_r == NULL) {
    ESP_LOGE(TAG, "Failed to get attribute for cluster 0x%04x, attribute 0x%04x", clusterID, attributeID);
    return;
    }

    memcpy(value_r->data_p, value, value_length);

    esp_zb_zcl_report_attr_cmd_req(&cmd);
}

uint16_t tvoc = 100;
reportAttribute(SENSOR_ENDPOINT, TVOC_CUSTOM_CLUSTER, 0, &tvoc, 2);

In the log, I receive the following messages:

I (434) DEMO: Cluster ID: 0x0000
I (434) DEMO: Attribute Count: 0
...
Failed to get attribute for cluster 0xfff2, attribute 0x0000

However, when I use standard clusters (e.g., temperature or humidity), I do not receive any error messages from the reportAttribute function, and I successfully receive values through ZigBee in zigbee2mqtt.

xieqinan commented 3 months ago

@aerosh

Could you please remove the ESP_ZB_ZCL_ATTR_MANUF_SPEC access from the custom attribute and try it again?

The ESP_ZB_ZCL_ATTR_MANUF_SPEC requires the specific manufacturer code you set. If the ESP_ZB_ZCL_ATTR_MANUF_SPEC access is necessary for you, you may be able to use esp_zb_zcl_get_manufacturer_attribute() to retrieve the desired attribute.

aerosh commented 3 months ago

@xieqinan , thank you! I removed ESP_ZB_ZCL_ATTR_MANUF_SPEC access from the custom attribute, but now the ESP32 reboots in a different part of the code. Here is the line where the issue occurs:

void reportAttribute(uint8_t endpoint, uint16_t clusterID, uint16_t attributeID, void *value, uint8_t value_length)
{
    ...
    esp_zb_zcl_report_attr_cmd_req(&cmd);
}

Here is the log of the problem:

I (2834) DEMO: Start network steering
I (2844) DEMO: Joined network successfully (Extended PAN ID: a2:77:e2:26:33:fd:74:b9, PAN ID: 0x1770, Channel:11)
Zigbee stack assertion failed /builds/thread_zigbee/esp-zboss/components/esp_zb_sdk/src/esp_zigbee_zcl_command.c:325

abort() was called at PC 0x42019d11 on core 0
0x42019d11: zb_assert at ??:?

Stack dump detected
Core  0 register dump:
MEPC    : 0x408007d2  RA      : 0x4080703a  SP      : 0x4081f100  GP      : 0x4080d9c4  
0x408007d2: panic_abort at /home/alexander/esp/v5.3/esp-idf/components/esp_system/panic.c:463
0x4080703a: __ubsan_include at /home/alexander/esp/v5.3/esp-idf/components/esp_system/ubsan.c:311

TP      : 0x4081f280  T0      : 0x37363534  T1      : 0x7271706f  T2      : 0x33323130  
S0/FP   : 0x00000004  S1      : 0x4081f164  A0      : 0x4081f12c  A1      : 0x4081f162  
A2      : 0x00000000  A3      : 0x4081f159  A4      : 0x00000001  A5      : 0x40813000  
A6      : 0x00000000  A7      : 0x76757473  S2      : 0x00000002  S3      : 0x0000fff2  
S4      : 0x00000000  S5      : 0x4081dd8c  S6      : 0x4081f1f8  S7      : 0x00000000  
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000  
T3      : 0x6e6d6c6b  T4      : 0x6a696867  T5      : 0x66656463  T6      : 0x62613938  
MSTATUS : 0x00001881  MTVEC   : 0x40800001  MCAUSE  : 0x00000007  MTVAL   : 0x00000000  
0x40800001: _vector_table at /home/alexander/esp/v5.3/esp-idf/components/riscv/vectors_intc.S:54

MHARTID : 0x00000000  

Backtrace:

panic_abort (details=details@entry=0x4081f12c "abort() was called at PC 0x42019d11 on core 0") at /home/alexander/esp/v5.3/esp-idf/components/esp_system/panic.c:463
463         *((volatile int *) 0) = 0; // NOLINT(clang-analyzer-core.NullDereference) should be an invalid operation on targets
#0  panic_abort (details=details@entry=0x4081f12c "abort() was called at PC 0x42019d11 on core 0") at /home/alexander/esp/v5.3/esp-idf/components/esp_system/panic.c:463
#1  0x4080703a in esp_system_abort (details=details@entry=0x4081f12c "abort() was called at PC 0x42019d11 on core 0") at /home/alexander/esp/v5.3/esp-idf/components/esp_system/port/esp_system_chip.c:92
#2  0x4080c026 in abort () at /home/alexander/esp/v5.3/esp-idf/components/newlib/abort.c:38
#3  0x42019d14 in zb_assert ()
Backtrace stopped: frame did not save the PC
ELF file SHA256: 78eaa13fc

Rebooting...
ESP-ROM:esp32h2-20221101
Build:Nov  1 2022
rst:0xc (SW_CPU),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x400031b6
SPIWP:0xee
mode:DIO, clock div:1
load:0x408460e0,len:0x17ac
load:0x4083cad0,len:0xef4
load:0x4083efd0,len:0x2cd4
entry 0x4083cada
xieqinan commented 3 months ago

@aerosh ,

I have test your code on my side, it works fine. Please refer to below patch.

0001-test-report.zip

aerosh commented 3 months ago

Thank you so much! That helped. I apologize for the incompetence and unfair creation of the bug. Thank you for your work and responsiveness