Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZHA Thermostat Occupancy attribute esp_zb_zcl_get_attribute causes core panic (TZ-1056) #403

Closed
3 tasks done
remenyo opened this issue Aug 14, 2024 · 4 comments
Closed
3 tasks done
Labels

Comments

@remenyo
Copy link

remenyo commented Aug 14, 2024

Answers checklist.

  • I have read the documentation ESP Zigbee SDK Programming Guide and tried the debugging tips, the issue is not addressed there.
  • I have updated ESP Zigbee libs (esp-zboss-lib and esp-zigbee-lib) to the latest version, with corresponding IDF version, and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.1.4

esp-zigbee-lib version.

1.4.1

esp-zboss-lib version.

1.4.1

Espressif SoC revision.

ESP32-C6

What is the expected behavior?

esp_zb_zcl_get_attribute should work on a read-only attribute, in this example, thermostat occupancy (Cluster ID: 0x0201, Attribute ID: 0x0002)

What is the actual behavior?

Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.
MEPC    : 0x4200898a  RA      : 0x4200898a  SP      : 0x40846590  GP      : 0x4080f0f0
TP      : 0x407f8aa0  T0      : 0x40022494  T1      : 0x40808b70  T2      : 0x00000000
S0/FP   : 0x00000000  S1      : 0x00000000  A0      : 0x00000001  A1      : 0x00000000
A2      : 0x40846648  A3      : 0x00000006  A4      : 0x00000001  A5      : 0x20001000
A6      : 0x00000001  A7      : 0x00000000  S2      : 0x00000000  S3      : 0x00000003
S4      : 0x00000000  S5      : 0x008b6b52  S6      : 0x4081a000  S7      : 0x00000005
S8      : 0x00000004  S9      : 0x000002bb  S10     : 0x00004e20  S11     : 0x03000000
T3      : 0x00000000  T4      : 0x00000000  T5      : 0x00000000  T6      : 0x00000000
MSTATUS : 0x00001881  MTVEC   : 0x40800001  MCAUSE  : 0x00000005  MTVAL   : 0x00000007

Steps to reproduce.

This works fine:

esp_zb_lock_acquire(pdTICKS_TO_MS(10000));
int16_t temp = (int16_t)(DS18B20::measure() * 100);
esp_zb_zcl_status_t status = esp_zb_zcl_set_attribute_val(1, 0x0201, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, 0, &temp, false);
LOGI("Write status: %d", status);
esp_zb_zcl_attr_t *attr = esp_zb_zcl_get_attribute(1, 0x0201, esp_zb_zcl_cluster_role_t::ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, 0);
esp_zb_lock_release();
if (attr->data_p != nullptr) {
    ESP_LOGI(TAG,"read temp %f with esp_zb_zcl_get_attribute command", static_cast<float>(*static_cast<int16_t *>(attr->data_p)) / 100.0);
}
else {
    ESP_LOGE(TAG,"attr->data_p = nullptr");
}

Outputs:

I :      temperature read from sensor: 27.50C
...
I :       Write status: 0
I :       read temp 27.500000 with esp_zb_zcl_get_attribute command

This does not work:

esp_zb_lock_acquire(pdTICKS_TO_MS(10000));
uint8_t buf = 0; // it's a map8 value, 0x00 is a valid value for it: Space is "Unoccupied"
esp_zb_zcl_status_t status = esp_zb_zcl_set_attribute_val(1, 0x0201, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, 2, &buf, false);
ESP_LOGI(TAG, "Write status: %d", status);
esp_zb_zcl_attr_t *attr = esp_zb_zcl_get_attribute(1, 0x0201, esp_zb_zcl_cluster_role_t::ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, 2);
esp_zb_lock_release();
if (attr->data_p != nullptr) {
    ESP_LOGI(TAG, "0x%02x", *static_cast<uint8_t *>(attr->data_p));
}
else {
    ESP_LOGE(TAG,"attr->data_p = nullptr");
}

Outputs:
I : Write status: 1
then crash.

More Information.

I hope that with the first (working) example I proved that I set up the thermostat cluster correctly, but feel free to check it:

// ...
thermostat_cfg.basic_cfg.power_source = 0x01; // "Mains (single phase)"
esp_zb_attribute_list_t *thermostat_cluster_attr_list = esp_zb_thermostat_cluster_create(&(thermostat_cfg.thermostat_cfg));
// ...
ESP_ERROR_CHECK(esp_zb_cluster_list_add_thermostat_cluster(cluster_list, thermostat_cluster_attr_list, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE));
// ...
esp_zb_ep_list_t *ep_list = esp_zb_ep_list_create();
esp_zb_endpoint_config_t endpoint_config = {
      .endpoint = 1,
      .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
      .app_device_id = ESP_ZB_HA_THERMOSTAT_DEVICE_ID,
      .app_device_version = 1,
};
esp_zb_ep_list_add_ep(ep_list, cluster_list, endpoint_config);
esp_zb_device_register(ep_list);
@remenyo remenyo added the Bug label Aug 14, 2024
@github-actions github-actions bot changed the title ZHA Thermostat Occupancy attribute esp_zb_zcl_get_attribute causes core panic ZHA Thermostat Occupancy attribute esp_zb_zcl_get_attribute causes core panic (TZ-1056) Aug 14, 2024
@xieqinan
Copy link
Contributor

@remenyo ,

The issue is caused by the absence of an attribute in the thermostat cluster. The esp_zb_thermostat_cluster_create() function only creates the mandatory attributes defined in the ZCL specification. The ZB_ZCL_ATTR_THERMOSTAT_OCCUPANCY_ID is an optional attribute, which requires to be added by the user. You can refer to the code below to resolve this issue.

uint8_t thermostat_occupancy = 0;
esp_zb_attribute_list_t *thermostat_cluster_attr_list = esp_zb_thermostat_cluster_create(&(thermostat_cfg.thermostat_cfg));
esp_zb_thermostat_cluster_add_attr(thermostat_cluster_attr_list, ESP_ZB_ZCL_ATTR_THERMOSTAT_OCCUPANCY_ID, &thermostat_occupancy);

@remenyo
Copy link
Author

remenyo commented Aug 16, 2024

Thank you for your help, this was the solution to my problem indeed.
So this is not a bug, optional attributes are not created with esp_zb_*clustername*_cluster_create

May I also ask how to traverse through the cluster list, to examine the list?

// this does _not_ work correctly
for (esp_zb_cluster_list_t *c = cluster_list; cluster_list != NULL; c = c->next)
{
    LOGI("Cluster ID: 0x%04x", c->cluster.cluster_id);
    for (esp_zb_attribute_list_t *a = c->cluster.attr_list; a != NULL; a = a->next)
    {
        LOGI("Attribute ID: 0x%04x, Type: 0x%02x, Access: 0x%02x)", a->attribute.id, a->attribute.type, a->attribute.access);
    }
}

This outputs:

I esp_zb_task:  Cluster ID: 0x0000
I esp_zb_task:  Cluster ID: 0x0b05
I esp_zb_task:  Attribute ID: 0x0000, Type: 0x00, Access: 0x00)
I esp_zb_task:  Attribute ID: 0xfffd, Type: 0x21, Access: 0x01)
I esp_zb_task:  Cluster ID: 0x0201
I esp_zb_task:  Attribute ID: 0x0000, Type: 0x00, Access: 0x00)
I esp_zb_task:  Attribute ID: 0xfffd, Type: 0x21, Access: 0x01)
I esp_zb_task:  Attribute ID: 0x0000, Type: 0x29, Access: 0x05)
I esp_zb_task:  Attribute ID: 0x0011, Type: 0x29, Access: 0x13)
I esp_zb_task:  Attribute ID: 0x0012, Type: 0x29, Access: 0x13)
I esp_zb_task:  Attribute ID: 0x001b, Type: 0x30, Access: 0x03)
I esp_zb_task:  Attribute ID: 0x001c, Type: 0x30, Access: 0x13)
...
Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.
Core  0 register dump:
MEPC    : 0x42006d18  RA      : 0x42006d56  SP      : 0x40851900  GP      : 0x4080f0f0
TP      : 0x40803e0c  T0      : 0x40022494  T1      : 0xffffffe0  T2      : 0x00000200
S0/FP   : 0x00000000  S1      : 0x00000001  A0      : 0x0000003f  A1      : 0x40857fec
A2      : 0x00000010  A3      : 0x00000800  A4      : 0x00000001  A5      : 0x00000004
A6      : 0x00000001  A7      : 0x42005444  S2      : 0x40857ef4  S3      : 0x42121000
S4      : 0x42121000  S5      : 0x00000000  S6      : 0x42121000  S7      : 0x00000000
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000
T3      : 0x00000000  T4      : 0x00000000  T5      : 0x0000000f  T6      : 0xffffffb1
MSTATUS : 0x00001881  MTVEC   : 0x40800001  MCAUSE  : 0x00000005  MTVAL   : 0x00000000
MHARTID : 0x00000000

@xieqinan
Copy link
Contributor

@remenyo ,

suggestion:

for (esp_zb_cluster_list_t *c = cluster_list; c != NULL; c = c->next)
{
    LOGI("Cluster ID: 0x%04x", c->cluster.cluster_id);
    for (esp_zb_attribute_list_t *a = c->cluster.attr_list; a != NULL; a = a->next)
    {
        LOGI("Attribute ID: 0x%04x, Type: 0x%02x, Access: 0x%02x)", a->attribute.id, a->attribute.type, a->attribute.access);
    }
}

@remenyo
Copy link
Author

remenyo commented Aug 16, 2024

Again, thank you very much.

@remenyo remenyo closed this as completed Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants