From 205a25913a23b040d3ebd3de4ae5e0173d82be99 Mon Sep 17 00:00:00 2001 From: Chirag Atal Date: Wed, 16 Mar 2022 12:56:18 +0530 Subject: [PATCH 1/2] esp_matter_attribute: Adding wrappers for all attribute_create() APIs esp_matter_cluster: Removing configs for attributes which are handled internally. esp_matter_attribute_utils: Renamed the old esp_matter_attribute files. --- components/esp_matter/esp_matter.h | 1 + .../esp_matter/esp_matter_attribute.cpp | 1506 ++++++----------- components/esp_matter/esp_matter_attribute.h | 288 ++-- .../esp_matter/esp_matter_attribute_utils.cpp | 1092 ++++++++++++ .../esp_matter/esp_matter_attribute_utils.h | 166 ++ components/esp_matter/esp_matter_cluster.cpp | 456 ++--- components/esp_matter/esp_matter_cluster.h | 154 +- components/esp_matter/esp_matter_core.cpp | 2 +- components/esp_matter/esp_matter_core.h | 2 +- components/esp_matter/esp_matter_endpoint.cpp | 23 +- components/esp_matter/esp_matter_endpoint.h | 22 - examples/bridge_zigbee/main/zigbee_bridge.h | 2 +- 12 files changed, 2119 insertions(+), 1595 deletions(-) create mode 100644 components/esp_matter/esp_matter_attribute_utils.cpp create mode 100644 components/esp_matter/esp_matter_attribute_utils.h diff --git a/components/esp_matter/esp_matter.h b/components/esp_matter/esp_matter.h index 971883614..9dacd06bd 100644 --- a/components/esp_matter/esp_matter.h +++ b/components/esp_matter/esp_matter.h @@ -20,6 +20,7 @@ application. */ #include +#include #include #include #include diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 473963fa0..eda99c528 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -12,1113 +12,587 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include #include -#include -#include -#include -#include -#include - -using chip::AttributeId; -using chip::ClusterId; -using chip::EndpointId; -using chip::Protocols::InteractionModel::Status; - -static const char *TAG = "esp_matter_attribute"; - -static esp_matter_attribute_callback_t attribute_callback = NULL; -static void *attribute_callback_priv_data = NULL; - -static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type); - -static esp_err_t esp_matter_attribute_console_handler(int argc, char **argv) +esp_matter_attribute_t *esp_matter_attribute_create_cluster_revision(esp_matter_cluster_t *cluster, uint16_t value) { - if (argc == 5 && strncmp(argv[0], "set", sizeof("set")) == 0) { - int endpoint_id = strtol((const char *)&argv[1][2], NULL, 16); - int cluster_id = strtol((const char *)&argv[2][2], NULL, 16); - int attribute_id = strtol((const char *)&argv[3][2], NULL, 16); - - /* Get type from matter_attribute */ - const EmberAfAttributeMetadata *matter_attribute = NULL; - EmberAfAttributeSearchRecord record = { - .endpoint = (EndpointId)endpoint_id, - .clusterId = (ClusterId)cluster_id, - .clusterMask = ESP_MATTER_CLUSTER_FLAG_SERVER, - .attributeId = (AttributeId)attribute_id, - }; - emAfReadOrWriteAttribute(&record, &matter_attribute, NULL, 0, false); - if (!matter_attribute) { - ESP_LOGE(TAG, "Matter attribute not found"); - return ESP_ERR_INVALID_ARG; - } - - /* Use the type to create the val and then update te attribute */ - esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType); - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) { - bool value = atoi(argv[4]); - val = esp_matter_bool(value); - } else if (type == ESP_MATTER_VAL_TYPE_INT8) { - int8_t value = atoi(argv[4]); - val = esp_matter_int8(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT8) { - uint8_t value = atoi(argv[4]); - val = esp_matter_uint8(value); - } else if (type == ESP_MATTER_VAL_TYPE_INT16) { - int16_t value = atoi(argv[4]); - val = esp_matter_int16(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT16) { - uint16_t value = atoi(argv[4]); - val = esp_matter_uint16(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT32) { - uint32_t value = atoi(argv[4]); - val = esp_matter_uint32(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT64) { - uint64_t value = atoi(argv[4]); - val = esp_matter_uint64(value); - } else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { - char *value = argv[4]; - val = esp_matter_char_str(value, strlen(value)); - } else { - ESP_LOGE(TAG, "Type not handled: %d", type); - return ESP_ERR_INVALID_ARG; - } - esp_matter_attribute_update(endpoint_id, cluster_id, attribute_id, &val); - } else if (argc == 4 && strncmp(argv[0], "get", sizeof("get")) == 0) { - int endpoint_id = strtol((const char *)&argv[1][2], NULL, 16); - int cluster_id = strtol((const char *)&argv[2][2], NULL, 16); - int attribute_id = strtol((const char *)&argv[3][2], NULL, 16); - - /* Directly print if esp matter data model is used */ - esp_matter_node_t *node = esp_matter_node_get(); - if (node) { - esp_matter_endpoint_t *endpoint = esp_matter_endpoint_get(node, endpoint_id); - esp_matter_cluster_t *cluster = esp_matter_cluster_get(endpoint, cluster_id); - esp_matter_attribute_t *attribute = esp_matter_attribute_get(cluster, attribute_id); - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - esp_matter_attribute_get_val(attribute, &val); - esp_matter_attribute_val_print(endpoint_id, cluster_id, attribute_id, &val); - return ESP_OK; - } - - /* Get type from matter_attribute if esp matter data model is not used */ - const EmberAfAttributeMetadata *matter_attribute = NULL; - EmberAfAttributeSearchRecord record = { - .endpoint = (EndpointId)endpoint_id, - .clusterId = (ClusterId)cluster_id, - .clusterMask = ESP_MATTER_CLUSTER_FLAG_SERVER, - .attributeId = (AttributeId)attribute_id, - }; - emAfReadOrWriteAttribute(&record, &matter_attribute, NULL, 0, false); - if (!matter_attribute) { - ESP_LOGE(TAG, "Matter attribute not found"); - return ESP_ERR_INVALID_ARG; - } - - /* Use the type to read the raw value and then print if esp matter data model is not used */ - esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType); - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) { - bool value = false; - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_bool(value); - } else if (type == ESP_MATTER_VAL_TYPE_INT8) { - int8_t value = 0; - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_int8(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT8) { - uint8_t value = 0; - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint8(value); - } else if (type == ESP_MATTER_VAL_TYPE_INT16) { - int16_t value = 0; - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_int16(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT16) { - uint16_t value = 0; - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint16(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT32) { - uint32_t value = 0; - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint32(value); - } else if (type == ESP_MATTER_VAL_TYPE_UINT64) { - uint64_t value = 0; - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint64(value); - } else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { - /* Get raw value */ - char value[256] = {0}; /* It can go upto 256 since only 1 byte (first) is used for size */ - esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - /* Get val from raw value */ - val = esp_matter_char_str(NULL, 0); - int data_size_len = val.val.a.t - val.val.a.s; - int data_count = 0; - memcpy(&data_count, &value[0], data_size_len); - val = esp_matter_char_str((char *)(value + data_size_len), data_count); - } else { - ESP_LOGE(TAG, "Type not handled: %d", type); - return ESP_ERR_INVALID_ARG; - } - esp_matter_attribute_val_print(endpoint_id, cluster_id, attribute_id, &val); - } else { - ESP_LOGE(TAG, "Incorrect arguments"); - return ESP_ERR_INVALID_ARG; - } - return ESP_OK; + return esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); } -static void esp_matter_attribute_register_commands() +esp_matter_attribute_t *esp_matter_attribute_create_feature_map(esp_matter_cluster_t *cluster, uint32_t value) { - static bool init_done = false; - if (init_done) { - return; - } - esp_matter_console_command_t command = { - .name = "attribute", - .description = "This can be used to simulate on-device control. " - "Usage: matter esp attribute [value]. " - "Example1: matter esp attribute set 0x0001 0x0006 0x0000 1. " - "Example2: matter esp attribute get 0x0001 0x0006 0x0000.", - .handler = esp_matter_attribute_console_handler, - }; - esp_matter_console_add_command(&command); - init_done = true; + return esp_matter_attribute_create(cluster, ZCL_FEATURE_MAP_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bitmap32(value)); } -esp_matter_attr_val_t esp_matter_invalid(void *val) +esp_matter_attribute_t *esp_matter_attribute_create_device_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_INVALID, - .val = { - .p = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_DEVICE_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); } -esp_matter_attr_val_t esp_matter_bool(bool val) +esp_matter_attribute_t *esp_matter_attribute_create_server_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_BOOLEAN, - .val = { - .b = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_SERVER_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); } -esp_matter_attr_val_t esp_matter_int(int val) +esp_matter_attribute_t *esp_matter_attribute_create_client_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_INTEGER, - .val = { - .i = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_CLIENT_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); } -esp_matter_attr_val_t esp_matter_float(float val) +esp_matter_attribute_t *esp_matter_attribute_create_parts_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_FLOAT, - .val = { - .f = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_PARTS_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); } -esp_matter_attr_val_t esp_matter_int8(int8_t val) +esp_matter_attribute_t *esp_matter_attribute_create_acl(esp_matter_cluster_t *cluster, uint8_t *value, uint16_t length, + uint16_t count) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_INT8, - .val = { - .i8 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_ACL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_array(value, length, count)); } -esp_matter_attr_val_t esp_matter_uint8(uint8_t val) +esp_matter_attribute_t *esp_matter_attribute_create_extension(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_UINT8, - .val = { - .u8 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_EXTENSION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_array(value, length, count)); } -esp_matter_attr_val_t esp_matter_int16(int16_t val) +esp_matter_attribute_t *esp_matter_attribute_create_data_model_revision(esp_matter_cluster_t *cluster, uint16_t value) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_INT16, - .val = { - .i16 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_DATA_MODEL_REVISION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); } -esp_matter_attr_val_t esp_matter_uint16(uint16_t val) +esp_matter_attribute_t *esp_matter_attribute_create_vendor_name(esp_matter_cluster_t *cluster, char *value, + uint16_t length) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_UINT16, - .val = { - .u16 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_VENDOR_NAME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); } -esp_matter_attr_val_t esp_matter_uint32(uint32_t val) +esp_matter_attribute_t *esp_matter_attribute_create_vendor_id(esp_matter_cluster_t *cluster, uint16_t value) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_UINT32, - .val = { - .u32 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_VENDOR_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); } -esp_matter_attr_val_t esp_matter_uint64(uint64_t val) +esp_matter_attribute_t *esp_matter_attribute_create_product_name(esp_matter_cluster_t *cluster, char *value, + uint16_t length) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_UINT64, - .val = { - .u64 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_PRODUCT_NAME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); } -esp_matter_attr_val_t esp_matter_enum8(uint8_t val) +esp_matter_attribute_t *esp_matter_attribute_create_product_id(esp_matter_cluster_t *cluster, uint16_t value) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_ENUM8, - .val = { - .u8 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_PRODUCT_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); } -esp_matter_attr_val_t esp_matter_bitmap8(uint8_t val) +esp_matter_attribute_t *esp_matter_attribute_create_node_label(esp_matter_cluster_t *cluster, char *value, + uint16_t length) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_BITMAP8, - .val = { - .u8 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_NODE_LABEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_char_str(value, length)); } -esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val) +esp_matter_attribute_t *esp_matter_attribute_create_location(esp_matter_cluster_t *cluster, char *value, + uint16_t length) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_BITMAP16, - .val = { - .u16 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_LOCATION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_char_str(value, length)); } -esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val) +esp_matter_attribute_t *esp_matter_attribute_create_hardware_version(esp_matter_cluster_t *cluster, uint16_t value) { - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_BITMAP32, - .val = { - .u32 = val, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_HARDWARE_VERSION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); } -esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size) +esp_matter_attribute_t *esp_matter_attribute_create_hardware_version_string(esp_matter_cluster_t *cluster, char *value, + uint16_t length) { - uint16_t data_size_len = 1; /* Number of bytes used to store the length */ - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_CHAR_STRING, - .val = { - .a = { - .b = (uint8_t *)val, - .s = data_size, - .n = data_size, - .t = (uint16_t)(data_size + data_size_len), - }, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_HARDWARE_VERSION_STRING_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } -esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size) +esp_matter_attribute_t *esp_matter_attribute_create_software_version(esp_matter_cluster_t *cluster, uint32_t value) { - uint16_t data_size_len = 1; /* Number of bytes used to store the length */ - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_OCTET_STRING, - .val = { - .a = { - .b = val, - .s = data_size, - .n = data_size, - .t = (uint16_t)(data_size + data_size_len), - }, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_SOFTWARE_VERSION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint32(value)); } -esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count) +esp_matter_attribute_t *esp_matter_attribute_create_software_version_string(esp_matter_cluster_t *cluster, char *value, + uint16_t length) { - uint16_t data_size_len = 2; /* Number of bytes used to store the length */ - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_ARRAY, - .val = { - .a = { - .b = val, - .s = data_size, - .n = count, - .t = (uint16_t)(data_size + data_size_len), - }, - }, - }; - return attr_val; + return esp_matter_attribute_create(cluster, ZCL_SOFTWARE_VERSION_STRING_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } -static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type) +esp_matter_attribute_t *esp_matter_attribute_create_binding(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) { - switch(attribute_type) { - case ZCL_BOOLEAN_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_BOOLEAN; - break; - - case ZCL_SINGLE_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_FLOAT; - break; - - case ZCL_ARRAY_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_ARRAY; - break; - - case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_CHAR_STRING; - break; - - case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_OCTET_STRING; - break; - - case ZCL_INT8S_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_INT8; - break; - - case ZCL_INT8U_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_UINT8; - break; - - case ZCL_INT16S_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_INT16; - break; - - case ZCL_INT16U_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_UINT16; - break; - - case ZCL_INT32U_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_UINT32; - break; - - case ZCL_INT64U_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_UINT64; - break; - - case ZCL_ENUM8_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_ENUM8; - break; - - case ZCL_BITMAP8_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_BITMAP8; - break; - - case ZCL_BITMAP16_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_BITMAP16; - break; - - case ZCL_BITMAP32_ATTRIBUTE_TYPE: - return ESP_MATTER_VAL_TYPE_BITMAP32; - break; - - default: - return ESP_MATTER_VAL_TYPE_INVALID; - break; - } - return ESP_MATTER_VAL_TYPE_INVALID; + return esp_matter_attribute_create(cluster, ZCL_BINDING_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_array(value, length, count)); } -esp_err_t esp_matter_attribute_get_type_and_val_default(esp_matter_attr_val_t *val, - EmberAfAttributeType *attribute_type, uint16_t *attribute_size, - EmberAfDefaultOrMinMaxAttributeValue *default_value) +esp_matter_attribute_t *esp_matter_attribute_create_default_ota_providers(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length) { - switch (val->type) { - case ESP_MATTER_VAL_TYPE_BOOLEAN: - *attribute_type = ZCL_BOOLEAN_ATTRIBUTE_TYPE; - *attribute_size = sizeof(bool); - *default_value = (uint16_t)val->val.b; - break; - - case ESP_MATTER_VAL_TYPE_INTEGER: - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *default_value = (uint16_t)val->val.i; - break; - - case ESP_MATTER_VAL_TYPE_FLOAT: - *attribute_type = ZCL_SINGLE_ATTRIBUTE_TYPE; - *attribute_size = sizeof(float); - *default_value = (uint8_t *)&val->val.f; - break; - - case ESP_MATTER_VAL_TYPE_ARRAY: - *attribute_type = ZCL_ARRAY_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.s; - *default_value = (uint8_t *)val->val.a.b; - break; - - case ESP_MATTER_VAL_TYPE_CHAR_STRING: - *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.s; - *default_value = (uint8_t *)val->val.a.b; - break; - - case ESP_MATTER_VAL_TYPE_BYTE_STRING: - ESP_LOGE(TAG, "esp_matter_attr_val_type_t not supported: %d", val->type); - break; - - case ESP_MATTER_VAL_TYPE_OCTET_STRING: - *attribute_type = ZCL_OCTET_STRING_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.s; - *default_value = (uint8_t *)val->val.a.b; - break; - - case ESP_MATTER_VAL_TYPE_INT8: - *attribute_type = ZCL_INT8S_ATTRIBUTE_TYPE; - *attribute_size = sizeof(int8_t); - *default_value = (uint16_t)val->val.i8; - break; - - case ESP_MATTER_VAL_TYPE_UINT8: - *attribute_type = ZCL_INT8U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *default_value = (uint16_t)val->val.u8; - break; - - case ESP_MATTER_VAL_TYPE_INT16: - *attribute_type = ZCL_INT16S_ATTRIBUTE_TYPE; - *attribute_size = sizeof(int16_t); - *default_value = (int16_t)val->val.i16; - break; - - case ESP_MATTER_VAL_TYPE_UINT16: - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *default_value = (uint16_t)val->val.u16; - break; - - case ESP_MATTER_VAL_TYPE_UINT32: - *attribute_type = ZCL_INT32U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint32_t); - *default_value = (uint8_t *)&val->val.u32; - break; - - case ESP_MATTER_VAL_TYPE_UINT64: - *attribute_type = ZCL_INT64U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint64_t); - *default_value = (uint8_t *)&val->val.u64; - break; - - case ESP_MATTER_VAL_TYPE_ENUM8: - *attribute_type = ZCL_ENUM8_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *default_value = (uint16_t)val->val.u8; - break; - - case ESP_MATTER_VAL_TYPE_BITMAP8: - *attribute_type = ZCL_BITMAP8_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *default_value = (uint16_t)val->val.u8; - break; - - case ESP_MATTER_VAL_TYPE_BITMAP16: - *attribute_type = ZCL_BITMAP16_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *default_value = (uint16_t)val->val.u16; - break; - - case ESP_MATTER_VAL_TYPE_BITMAP32: - *attribute_type = ZCL_BITMAP32_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint32_t); - *default_value = (uint8_t *)&val->val.u32; - break; - - default: - ESP_LOGE(TAG, "esp_matter_attr_val_type_t not handled: %d", val->type); - break; - } - - return ESP_OK; + return esp_matter_attribute_create(cluster, ZCL_DEFAULT_OTA_PROVIDERS_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, esp_matter_octet_str(value, length)); } -static esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, - uint16_t *attribute_size, uint8_t *value) +esp_matter_attribute_t *esp_matter_attribute_create_update_possible(esp_matter_cluster_t *cluster, bool value) { - switch (val->type) { - case ESP_MATTER_VAL_TYPE_BOOLEAN: - if (attribute_type) { - *attribute_type = ZCL_BOOLEAN_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(bool); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.b, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_INTEGER: - if (attribute_type) { - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint16_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.i, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_FLOAT: - if (attribute_type) { - *attribute_type = ZCL_SINGLE_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(float); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.f, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_ARRAY: - if (attribute_type) { - *attribute_type = ZCL_ARRAY_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = val->val.a.t; - } - if (value) { - int data_size_len = val->val.a.t - val->val.a.s; - memcpy(value, (uint8_t *)&val->val.a.s, data_size_len); - memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len)); - } - break; - - case ESP_MATTER_VAL_TYPE_CHAR_STRING: - if (attribute_type) { - *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = val->val.a.t; - } - if (value) { - int data_size_len = val->val.a.t - val->val.a.s; - memcpy(value, (uint8_t *)&val->val.a.s, data_size_len); - memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len)); - } - break; - - case ESP_MATTER_VAL_TYPE_BYTE_STRING: - ESP_LOGE(TAG, "esp_matter_attr_val_type_t not supported: %d", val->type); - break; - - case ESP_MATTER_VAL_TYPE_OCTET_STRING: - if (attribute_type) { - *attribute_type = ZCL_OCTET_STRING_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = val->val.a.t; - } - if (value) { - int data_size_len = val->val.a.t - val->val.a.s; - memcpy(value, (uint8_t *)&val->val.a.s, data_size_len); - memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len)); - } - break; - - case ESP_MATTER_VAL_TYPE_INT8: - if (attribute_type) { - *attribute_type = ZCL_INT8S_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(int8_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.i8, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_UINT8: - if (attribute_type) { - *attribute_type = ZCL_INT8U_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint8_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_INT16: - if (attribute_type) { - *attribute_type = ZCL_INT16S_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(int16_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.i16, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_UINT16: - if (attribute_type) { - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint16_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u16, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_UINT32: - if (attribute_type) { - *attribute_type = ZCL_INT32U_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint32_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u32, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_UINT64: - if (attribute_type) { - *attribute_type = ZCL_INT64U_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint64_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u64, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_ENUM8: - if (attribute_type) { - *attribute_type = ZCL_ENUM8_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint8_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_BITMAP8: - if (attribute_type) { - *attribute_type = ZCL_BITMAP8_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint8_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_BITMAP16: - if (attribute_type) { - *attribute_type = ZCL_BITMAP16_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint16_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u16, *attribute_size); - } - break; - - case ESP_MATTER_VAL_TYPE_BITMAP32: - if (attribute_type) { - *attribute_type = ZCL_BITMAP32_ATTRIBUTE_TYPE; - } - if (attribute_size) { - *attribute_size = sizeof(uint32_t); - } - if (value) { - memcpy(value, (uint8_t *)&val->val.u32, *attribute_size); - } - break; - - default: - ESP_LOGE(TAG, "esp_matter_attr_val_type_t not handled: %d", val->type); - break; - } - - return ESP_OK; + return esp_matter_attribute_create(cluster, ZCL_UPDATE_POSSIBLE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bool(value)); } -static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttributeType attribute_type, - uint16_t attribute_size, uint8_t *value) +esp_matter_attribute_t *esp_matter_attribute_create_update_state(esp_matter_cluster_t *cluster, uint8_t value) { - switch (attribute_type) { - case ZCL_BOOLEAN_ATTRIBUTE_TYPE: - { - bool attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(bool)); - *val = esp_matter_bool(attribute_value); - break; - } - - case ZCL_ARRAY_ATTRIBUTE_TYPE: - { - *val = esp_matter_array(NULL, 0, 0); - int data_size_len = val->val.a.t - val->val.a.s; - int data_count = 0; - memcpy(&data_count, &value[0], data_size_len); - *val = esp_matter_array((value + data_size_len), attribute_size, data_count); - break; - } - - case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: - { - *val = esp_matter_char_str(NULL, 0); - int data_size_len = val->val.a.t - val->val.a.s; - int data_count = 0; - memcpy(&data_count, &value[0], data_size_len); - *val = esp_matter_char_str((char *)(value + data_size_len), data_count); - break; - } - - case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: - { - *val = esp_matter_octet_str(NULL, 0); - int data_size_len = val->val.a.t - val->val.a.s; - int data_count = 0; - memcpy(&data_count, &value[0], data_size_len); - *val = esp_matter_octet_str((value + data_size_len), data_count); - break; - } - - case ZCL_INT8S_ATTRIBUTE_TYPE: - { - int8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(int8_t)); - *val = esp_matter_int8(attribute_value); - break; - } - - case ZCL_INT8U_ATTRIBUTE_TYPE: - { - uint8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); - *val = esp_matter_uint8(attribute_value); - break; - } - - case ZCL_INT16S_ATTRIBUTE_TYPE: - { - int16_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(int16_t)); - *val = esp_matter_int16(attribute_value); - break; - } - - case ZCL_INT16U_ATTRIBUTE_TYPE: - { - uint16_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint16_t)); - *val = esp_matter_uint16(attribute_value); - break; - } - - case ZCL_INT32U_ATTRIBUTE_TYPE: - { - uint32_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint32_t)); - *val = esp_matter_uint32(attribute_value); - break; - } - - case ZCL_INT64U_ATTRIBUTE_TYPE: - { - uint64_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint64_t)); - *val = esp_matter_uint64(attribute_value); - break; - } - - case ZCL_ENUM8_ATTRIBUTE_TYPE: - { - uint8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); - *val = esp_matter_enum8(attribute_value); - break; - } - - case ZCL_BITMAP8_ATTRIBUTE_TYPE: - { - uint8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); - *val = esp_matter_bitmap8(attribute_value); - break; - } - - case ZCL_BITMAP16_ATTRIBUTE_TYPE: - { - uint16_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint16_t)); - *val = esp_matter_bitmap16(attribute_value); - break; - } - - default: - *val = esp_matter_invalid(NULL); - break; - } - - return ESP_OK; + return esp_matter_attribute_create(cluster, ZCL_UPDATE_STATE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); } -void esp_matter_attribute_val_print(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val) +esp_matter_attribute_t *esp_matter_attribute_create_update_state_progress(esp_matter_cluster_t *cluster, uint8_t value) { - if (val->type == ESP_MATTER_VAL_TYPE_BOOLEAN) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %d **********", endpoint_id, - cluster_id, attribute_id, val->val.b); - } else if (val->type == ESP_MATTER_VAL_TYPE_INTEGER) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %d **********", endpoint_id, - cluster_id, attribute_id, val->val.i); - } else if (val->type == ESP_MATTER_VAL_TYPE_FLOAT) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %f **********", endpoint_id, - cluster_id, attribute_id, val->val.f); - } else if (val->type == ESP_MATTER_VAL_TYPE_UINT8 || val->type == ESP_MATTER_VAL_TYPE_BITMAP8) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %d **********", endpoint_id, - cluster_id, attribute_id, val->val.u8); - } else if (val->type == ESP_MATTER_VAL_TYPE_INT16) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %d **********", endpoint_id, - cluster_id, attribute_id, val->val.i16); - } else if (val->type == ESP_MATTER_VAL_TYPE_UINT16) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %d **********", endpoint_id, - cluster_id, attribute_id, val->val.u16); - } else if (val->type == ESP_MATTER_VAL_TYPE_UINT32) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %d **********", endpoint_id, - cluster_id, attribute_id, val->val.u32); - } else if (val->type == ESP_MATTER_VAL_TYPE_UINT64) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %lld **********", endpoint_id, - cluster_id, attribute_id, val->val.u64); - } else if (val->type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is %.*s **********", endpoint_id, - cluster_id, attribute_id, val->val.a.s, val->val.a.b); - } else { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%08X's Attribute 0x%04X is **********", - endpoint_id, cluster_id, attribute_id, val->type); - } + return esp_matter_attribute_create(cluster, ZCL_UPDATE_STATE_PROGRESS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); } -esp_err_t esp_matter_attribute_callback_set(esp_matter_attribute_callback_t callback, void *priv_data) +esp_matter_attribute_t *esp_matter_attribute_create_breadcrumb(esp_matter_cluster_t *cluster, uint64_t value) { - attribute_callback = callback; - attribute_callback_priv_data = priv_data; - - /* Other initialisations */ - esp_matter_attribute_register_commands(); - return ESP_OK; + return esp_matter_attribute_create(cluster, ZCL_BREADCRUMB_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_uint64(value)); } -esp_err_t esp_matter_attribute_get_val_raw(int endpoint_id, int cluster_id, int attribute_id, uint8_t *value, - uint16_t attribute_size) +esp_matter_attribute_t *esp_matter_attribute_create_basic_commissioning_info(esp_matter_cluster_t *cluster, + uint8_t *value, uint16_t length, + uint16_t count) { - /* Take lock if not already taken */ - esp_matter_lock_status_t lock_status = esp_matter_chip_stack_lock(portMAX_DELAY); - if (lock_status == ESP_MATTER_LOCK_FAILED) { - ESP_LOGE(TAG, "Could not get task context"); - return ESP_FAIL; - } - - EmberAfStatus status = emberAfReadServerAttribute(endpoint_id, cluster_id, attribute_id, value, attribute_size); - if (status != EMBER_ZCL_STATUS_SUCCESS) { - ESP_LOGE(TAG, "Error getting raw value from matter: 0x%x", status); - if (lock_status == ESP_MATTER_LOCK_SUCCESS) { - esp_matter_chip_stack_unlock(); - } - return ESP_FAIL; - } - if (lock_status == ESP_MATTER_LOCK_SUCCESS) { - esp_matter_chip_stack_unlock(); - } - return ESP_OK; + return esp_matter_attribute_create(cluster, ZCL_BASICCOMMISSIONINGINFO_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); } -esp_err_t esp_matter_attribute_update(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val) +esp_matter_attribute_t *esp_matter_attribute_create_regulatory_config(esp_matter_cluster_t *cluster, uint8_t value) { - /* Take lock if not already taken */ - esp_matter_lock_status_t lock_status = esp_matter_chip_stack_lock(portMAX_DELAY); - if (lock_status == ESP_MATTER_LOCK_FAILED) { - ESP_LOGE(TAG, "Could not get task context"); - return ESP_FAIL; - } - - /* Get size */ - EmberAfAttributeType attribute_type = 0; - uint16_t attribute_size = 0; - get_data_from_attr_val(val, &attribute_type, &attribute_size, NULL); - - /* Get value */ - uint8_t *value = (uint8_t *)calloc(1, attribute_size); - if (!value) { - ESP_LOGE(TAG, "Could not allocate value buffer"); - if (lock_status == ESP_MATTER_LOCK_SUCCESS) { - esp_matter_chip_stack_unlock(); - } - return ESP_ERR_NO_MEM; - } - get_data_from_attr_val(val, &attribute_type, &attribute_size, value); - - /* Update matter */ - EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; - if (emberAfContainsServer(endpoint_id, cluster_id)) { - status = emberAfWriteServerAttribute(endpoint_id, cluster_id, attribute_id, value, attribute_type); - if (status != EMBER_ZCL_STATUS_SUCCESS) { - ESP_LOGE(TAG, "Error updating attribute to matter"); - free(value); - if (lock_status == ESP_MATTER_LOCK_SUCCESS) { - esp_matter_chip_stack_unlock(); - } - return ESP_FAIL; - } - } - free(value); - if (lock_status == ESP_MATTER_LOCK_SUCCESS) { - esp_matter_chip_stack_unlock(); - } - return ESP_OK; + return esp_matter_attribute_create(cluster, ZCL_REGULATORYCONFIG_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); } -Status MatterPreAttributeChangeCallback(const chip::app::ConcreteAttributePath &path, uint8_t mask, uint8_t type, - uint16_t size, uint8_t *value) +esp_matter_attribute_t *esp_matter_attribute_create_location_capability(esp_matter_cluster_t *cluster, uint8_t value) { - int endpoint_id = path.mEndpointId; - int cluster_id = path.mClusterId; - int attribute_id = path.mAttributeId; - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - get_attr_val_from_data(&val, type, size, value); - - /* Print */ - esp_matter_attribute_val_print(endpoint_id, cluster_id, attribute_id, &val); - - /* Callback to application */ - if (attribute_callback) { - esp_err_t err = attribute_callback(ESP_MATTER_CALLBACK_TYPE_PRE_ATTRIBUTE, endpoint_id, cluster_id, - attribute_id, &val, attribute_callback_priv_data); - if (err != ESP_OK) { - return Status::Failure; - } - } - return Status::Success; + return esp_matter_attribute_create(cluster, ZCL_LOCATIONCAPABILITY_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); } -void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &path, uint8_t mask, uint8_t type, - uint16_t size, uint8_t *value) +esp_matter_attribute_t *esp_matter_attribute_create_max_networks(esp_matter_cluster_t *cluster, uint8_t value) { - int endpoint_id = path.mEndpointId; - int cluster_id = path.mClusterId; - int attribute_id = path.mAttributeId; - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - get_attr_val_from_data(&val, type, size, value); - - /* Callback to application */ - if (attribute_callback) { - attribute_callback(ESP_MATTER_CALLBACK_TYPE_POST_ATTRIBUTE, endpoint_id, cluster_id, attribute_id, &val, - attribute_callback_priv_data); - } + return esp_matter_attribute_create(cluster, ZCL_MAX_NETWORKS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); } -EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint_id, ClusterId cluster_id, - const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer, - uint16_t max_read_length) +esp_matter_attribute_t *esp_matter_attribute_create_networks(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) { - /* Get value */ - int attribute_id = matter_attribute->attributeId; - esp_matter_node_t *node = esp_matter_node_get(); - if (!node) { - return EMBER_ZCL_STATUS_FAILURE; - } - esp_matter_endpoint_t *endpoint = esp_matter_endpoint_get(node, endpoint_id); - esp_matter_cluster_t *cluster = esp_matter_cluster_get(endpoint, cluster_id); - esp_matter_attribute_t *attribute = esp_matter_attribute_get(cluster, attribute_id); - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - esp_matter_attribute_get_val(attribute, &val); - - /* Print */ - esp_matter_attribute_val_print(endpoint_id, cluster_id, attribute_id, &val); - - /* Get size */ - uint16_t attribute_size = 0; - get_data_from_attr_val(&val, NULL, &attribute_size, NULL); - if (attribute_size > max_read_length) { - ESP_LOGE(TAG, "Insufficient space for reading attribute: required: %d, max: %d", attribute_size, - max_read_length); - return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE; - } - - /* Assign value */ - get_data_from_attr_val(&val, NULL, &attribute_size, buffer); - return EMBER_ZCL_STATUS_SUCCESS; + return esp_matter_attribute_create(cluster, ZCL_NETWORKS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); } -EmberAfStatus emberAfExternalAttributeWriteCallback(EndpointId endpoint_id, ClusterId cluster_id, - const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer) +esp_matter_attribute_t *esp_matter_attribute_create_scan_max_time_seconds(esp_matter_cluster_t *cluster, uint8_t value) { - /* Get value */ - int attribute_id = matter_attribute->attributeId; - esp_matter_node_t *node = esp_matter_node_get(); - if (!node) { - return EMBER_ZCL_STATUS_FAILURE; - } - esp_matter_endpoint_t *endpoint = esp_matter_endpoint_get(node, endpoint_id); - esp_matter_cluster_t *cluster = esp_matter_cluster_get(endpoint, cluster_id); - esp_matter_attribute_t *attribute = esp_matter_attribute_get(cluster, attribute_id); - - /* Get val */ - /* This creates a new variable val, and stores the new attribute value in the new variable. - The value in esp-matter data model is updated only when esp_matter_attribute_set_val() is called */ - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - get_attr_val_from_data(&val, matter_attribute->attributeType, matter_attribute->size, buffer); - - /* Update val */ - esp_matter_attribute_set_val(attribute, &val); - return EMBER_ZCL_STATUS_SUCCESS; + return esp_matter_attribute_create(cluster, ZCL_SCAN_MAX_TIME_SECONDS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_connect_max_time_seconds(esp_matter_cluster_t *cluster, + uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_CONNECT_MAX_TIME_SECONDS_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_interface_enabled(esp_matter_cluster_t *cluster, bool value) +{ + return esp_matter_attribute_create(cluster, ZCL_INTERFACE_ENABLED_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_bool(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_last_networking_status(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_LAST_NETWORKING_STATUS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_last_network_id(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length) +{ + return esp_matter_attribute_create(cluster, ZCL_LAST_NETWORK_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_octet_str(value, length)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_last_connect_error_value(esp_matter_cluster_t *cluster, + uint32_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_LAST_CONNECT_ERROR_VALUE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint32(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_network_interfaces(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) +{ + return esp_matter_attribute_create(cluster, ZCL_NETWORK_INTERFACES_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_reboot_count(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_REBOOT_COUNT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_window_status(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_WINDOW_STATUS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_admin_fabric_index(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_ADMIN_FABRIC_INDEX_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_admin_vendor_id(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_ADMIN_VENDOR_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_nocs(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) +{ + return esp_matter_attribute_create(cluster, ZCL_NOCS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_fabrics(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) +{ + return esp_matter_attribute_create(cluster, ZCL_FABRICS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_supported_fabrics(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_SUPPORTED_FABRICS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_commissioned_fabrics(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_COMMISSIONED_FABRICS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_trusted_root_certificates(esp_matter_cluster_t *cluster, + uint8_t *value, uint16_t length, + uint16_t count) +{ + return esp_matter_attribute_create(cluster, ZCL_TRUSTED_ROOTS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_current_fabric_index(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_CURRENT_FABRIC_INDEX_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_group_key_map(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) +{ + return esp_matter_attribute_create(cluster, ZCL_GROUP_KEY_MAP_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_array(value, length, count)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_group_table(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) +{ + return esp_matter_attribute_create(cluster, ZCL_GROUP_TABLE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_max_groups_per_fabric(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_MAX_GROUPS_PER_FABRIC_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_max_group_keys_per_fabric(esp_matter_cluster_t *cluster, + uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_MAX_GROUP_KEYS_PER_FABRIC_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_identify_time(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_identify_type(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_IDENTIFY_TYPE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_group_name_support(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_GROUP_NAME_SUPPORT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bitmap8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_scene_count(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_SCENE_COUNT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_current_scene(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_CURRENT_SCENE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_current_group(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_CURRENT_GROUP_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_scene_valid(esp_matter_cluster_t *cluster, bool value) +{ + return esp_matter_attribute_create(cluster, ZCL_SCENE_VALID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bool(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_scene_name_support(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_SCENE_NAME_SUPPORT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bitmap8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_on_off(esp_matter_cluster_t *cluster, bool value) +{ + return esp_matter_attribute_create(cluster, ZCL_ON_OFF_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bool(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_current_level(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_on_level(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_ON_LEVEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_options(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_OPTIONS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_bitmap8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_current_hue(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_current_saturation(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_color_mode(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_color_control_options(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_OPTIONS_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, esp_matter_bitmap8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_enhanced_color_mode(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_ENHANCED_COLOR_MODE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_color_capabilities(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_COLOR_CAPABILITIES_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_bitmap16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_fan_mode(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_FAN_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_fan_mode_sequence(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_FAN_MODE_SEQUENCE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_local_temperature(esp_matter_cluster_t *cluster, uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_LOCAL_TEMPERATURE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_occupied_cooling_setpoint(esp_matter_cluster_t *cluster, + uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_occupied_heating_setpoint(esp_matter_cluster_t *cluster, + uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, esp_matter_uint16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_control_sequence_of_operation(esp_matter_cluster_t *cluster, + uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_CONTROL_SEQUENCE_OF_OPERATION_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_system_mode(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_lock_state(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_LOCK_STATE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_lock_type(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_LOCK_TYPE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_actuator_enabled(esp_matter_cluster_t *cluster, bool value) +{ + return esp_matter_attribute_create(cluster, ZCL_ACTUATOR_ENABLED_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bool(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_auto_relock_time(esp_matter_cluster_t *cluster, uint32_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_AUTO_RELOCK_TIME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_bitmap32(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_operating_mode(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_OPERATING_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_supported_operating_modes(esp_matter_cluster_t *cluster, + uint16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_SUPPORTED_OPERATING_MODES_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_bitmap16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_bridged_device_basic_node_label(esp_matter_cluster_t *cluster, + char *value, uint16_t length) +{ + return esp_matter_attribute_create(cluster, ZCL_NODE_LABEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_reachable(esp_matter_cluster_t *cluster, bool value) +{ + return esp_matter_attribute_create(cluster, ZCL_REACHABLE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_bool(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_label_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count) +{ + return esp_matter_attribute_create(cluster, ZCL_LABEL_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_array(value, length, count)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_number_of_positions(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_NUMBER_OF_POSITIONS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_current_position(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_CURRENT_POSITION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_multi_press_max(esp_matter_cluster_t *cluster, uint8_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_MULTI_PRESS_MAX_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_temperature_measured_value(esp_matter_cluster_t *cluster, + int16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_TEMP_MEASURED_VALUE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_int16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_temperature_min_measured_value(esp_matter_cluster_t *cluster, + int16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_TEMP_MIN_MEASURED_VALUE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_int16(value)); +} + +esp_matter_attribute_t *esp_matter_attribute_create_temperature_max_measured_value(esp_matter_cluster_t *cluster, + int16_t value) +{ + return esp_matter_attribute_create(cluster, ZCL_TEMP_MAX_MEASURED_VALUE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_int16(value)); } diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index eaf513c57..1038e4c41 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -14,155 +14,185 @@ #pragma once -#include -#include -#include +#include +#include -#define REMAP_TO_RANGE(value, from, to) ((value * to) / from) +/** cluster: global */ +esp_matter_attribute_t *esp_matter_attribute_create_cluster_revision(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_feature_map(esp_matter_cluster_t *cluster, uint32_t value); -/** ESP Matter Attribute Value type */ -typedef enum { - /** Invalid */ - ESP_MATTER_VAL_TYPE_INVALID = 0, - /** Boolean */ - ESP_MATTER_VAL_TYPE_BOOLEAN, - /** Integer. Mapped to a 32 bit signed integer */ - ESP_MATTER_VAL_TYPE_INTEGER, - /** Floating point number */ - ESP_MATTER_VAL_TYPE_FLOAT, - /** Array Eg. [1,2,3] */ - ESP_MATTER_VAL_TYPE_ARRAY, - /** Byte String Eg. "123" */ - ESP_MATTER_VAL_TYPE_CHAR_STRING, - /** Byte String Eg. [0x01, 0x20] */ - ESP_MATTER_VAL_TYPE_BYTE_STRING, - /** Octet String Eg. [0x01, 0x20] */ - ESP_MATTER_VAL_TYPE_OCTET_STRING, - /** 8 bit signed integer */ - ESP_MATTER_VAL_TYPE_INT8, - /** 8 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT8, - /** 16 bit signed integer */ - ESP_MATTER_VAL_TYPE_INT16, - /** 16 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT16, - /** 32 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT32, - /** 64 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT64, - /** 8 bit enum */ - ESP_MATTER_VAL_TYPE_ENUM8, - /** 8 bit bitmap */ - ESP_MATTER_VAL_TYPE_BITMAP8, - /** 16 bit bitmap */ - ESP_MATTER_VAL_TYPE_BITMAP16, - /** 32 bit bitmap */ - ESP_MATTER_VAL_TYPE_BITMAP32, -} esp_matter_val_type_t; +/** cluster: descriptor */ +esp_matter_attribute_t *esp_matter_attribute_create_device_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_server_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_client_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_parts_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); -/* ESP Matter Value */ -typedef union { - /** Boolean */ - bool b; - /** Integer */ - int i; - /** Float */ - float f; - /** 8 bit signed integer */ - int8_t i8; - /** 8 bit unsigned integer */ - uint8_t u8; - /** 16 bit signed integer */ - int16_t i16; - /** 16 bit unsigned integer */ - uint16_t u16; - /** 32 bit unsigned integer */ - uint32_t u32; - /** 64 bit unsigned integer */ - uint64_t u64; - /** Array */ - struct { - /** Buffer */ - uint8_t *b; - /** Data size */ - uint16_t s; - /** Data count */ - uint16_t n; - /** Total size */ - uint16_t t; - } a; - /** Pointer */ - void *p; -} esp_matter_val_t; +/** cluster: access control */ +esp_matter_attribute_t *esp_matter_attribute_create_acl(esp_matter_cluster_t *cluster, uint8_t *value, uint16_t length, + uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_extension(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); -/* ESP Matter Attribute Value */ -typedef struct { - /** Type of Value */ - esp_matter_val_type_t type; - /** Actual value. Depends on the type */ - esp_matter_val_t val; -} esp_matter_attr_val_t; +/** cluster: basic */ +esp_matter_attribute_t *esp_matter_attribute_create_data_model_revision(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_vendor_name(esp_matter_cluster_t *cluster, char *value, + uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_vendor_id(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_product_name(esp_matter_cluster_t *cluster, char *value, + uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_product_id(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_node_label(esp_matter_cluster_t *cluster, char *value, + uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_location(esp_matter_cluster_t *cluster, char *value, + uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_hardware_version(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_hardware_version_string(esp_matter_cluster_t *cluster, char *value, + uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_software_version(esp_matter_cluster_t *cluster, uint32_t value); +esp_matter_attribute_t *esp_matter_attribute_create_software_version_string(esp_matter_cluster_t *cluster, char *value, + uint16_t length); -/*** Attribute val APIs ***/ -/** Invalid */ -esp_matter_attr_val_t esp_matter_invalid(void *val); +/** cluster: binding */ +esp_matter_attribute_t *esp_matter_attribute_create_binding(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); -/** Boolean */ -esp_matter_attr_val_t esp_matter_bool(bool val); +/** cluster: ota requestor */ +esp_matter_attribute_t *esp_matter_attribute_create_default_ota_providers(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_update_possible(esp_matter_cluster_t *cluster, bool value); +esp_matter_attribute_t *esp_matter_attribute_create_update_state(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_update_state_progress(esp_matter_cluster_t *cluster, uint8_t value); -/** Integer */ -esp_matter_attr_val_t esp_matter_int(int val); +/** cluster: general commissioning */ +esp_matter_attribute_t *esp_matter_attribute_create_breadcrumb(esp_matter_cluster_t *cluster, uint64_t value); +esp_matter_attribute_t *esp_matter_attribute_create_basic_commissioning_info(esp_matter_cluster_t *cluster, + uint8_t *value, uint16_t length, + uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_regulatory_config(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_location_capability(esp_matter_cluster_t *cluster, uint8_t value); -/** Float */ -esp_matter_attr_val_t esp_matter_float(float val); +/** cluster: network commissioning */ +esp_matter_attribute_t *esp_matter_attribute_create_max_networks(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_networks(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_scan_max_time_seconds(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_connect_max_time_seconds(esp_matter_cluster_t *cluster, + uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_interface_enabled(esp_matter_cluster_t *cluster, bool value); +esp_matter_attribute_t *esp_matter_attribute_create_last_networking_status(esp_matter_cluster_t *cluster, + uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_last_network_id(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_last_connect_error_value(esp_matter_cluster_t *cluster, + uint32_t value); -/** 8 bit integer */ -esp_matter_attr_val_t esp_matter_int8(int8_t val); +/** cluster: general diagnostics */ +esp_matter_attribute_t *esp_matter_attribute_create_network_interfaces(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_reboot_count(esp_matter_cluster_t *cluster, uint16_t value); -/** 8 bit unsigned integer */ -esp_matter_attr_val_t esp_matter_uint8(uint8_t val); +/** cluster: administrator commissioning */ +esp_matter_attribute_t *esp_matter_attribute_create_window_status(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_admin_fabric_index(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_admin_vendor_id(esp_matter_cluster_t *cluster, uint16_t value); -/** 16 bit signed integer */ -esp_matter_attr_val_t esp_matter_int16(int16_t val); +/** cluster: operational credentials */ +esp_matter_attribute_t *esp_matter_attribute_create_nocs(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_fabrics(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_supported_fabrics(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_commissioned_fabrics(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_trusted_root_certificates(esp_matter_cluster_t *cluster, + uint8_t *value, uint16_t length, + uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_current_fabric_index(esp_matter_cluster_t *cluster, uint8_t value); -/** 16 bit unsigned integer */ -esp_matter_attr_val_t esp_matter_uint16(uint16_t val); +/** cluster: group key management */ +esp_matter_attribute_t *esp_matter_attribute_create_group_key_map(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_group_table(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); +esp_matter_attribute_t *esp_matter_attribute_create_max_groups_per_fabric(esp_matter_cluster_t *cluster, + uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_max_group_keys_per_fabric(esp_matter_cluster_t *cluster, + uint16_t value); -/** 32 bit unsigned integer */ -esp_matter_attr_val_t esp_matter_uint32(uint32_t val); +/** cluster: identify */ +esp_matter_attribute_t *esp_matter_attribute_create_identify_time(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_identify_type(esp_matter_cluster_t *cluster, uint8_t value); -/** 64 bit unsigned integer */ -esp_matter_attr_val_t esp_matter_uint64(uint64_t val); +/** cluster: groups */ +esp_matter_attribute_t *esp_matter_attribute_create_group_name_support(esp_matter_cluster_t *cluster, uint8_t value); -/** 8 bit enum */ -esp_matter_attr_val_t esp_matter_enum8(uint8_t val); +/** cluster: scenes */ +esp_matter_attribute_t *esp_matter_attribute_create_scene_count(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_current_scene(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_current_group(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_scene_valid(esp_matter_cluster_t *cluster, bool value); +esp_matter_attribute_t *esp_matter_attribute_create_scene_name_support(esp_matter_cluster_t *cluster, uint8_t value); -/** 8 bit bitmap */ -esp_matter_attr_val_t esp_matter_bitmap8(uint8_t val); +/** cluster: on off */ +esp_matter_attribute_t *esp_matter_attribute_create_on_off(esp_matter_cluster_t *cluster, bool value); -/** 16 bit bitmap */ -esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val); +/** cluster: level control */ +esp_matter_attribute_t *esp_matter_attribute_create_current_level(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_on_level(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_options(esp_matter_cluster_t *cluster, uint8_t value); -/** 32 bit bitmap */ -esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val); +/** cluster: color control */ +esp_matter_attribute_t *esp_matter_attribute_create_current_hue(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_current_saturation(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_color_mode(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_color_control_options(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_enhanced_color_mode(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_color_capabilities(esp_matter_cluster_t *cluster, uint16_t value); -/** Character string */ -esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size); +/** cluster: fan control */ +esp_matter_attribute_t *esp_matter_attribute_create_fan_mode(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_fan_mode_sequence(esp_matter_cluster_t *cluster, uint8_t value); -/** Octet string */ -esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size); +/** cluster: thermostat */ +esp_matter_attribute_t *esp_matter_attribute_create_local_temperature(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_occupied_cooling_setpoint(esp_matter_cluster_t *cluster, + uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_occupied_heating_setpoint(esp_matter_cluster_t *cluster, + uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_control_sequence_of_operation(esp_matter_cluster_t *cluster, + uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_system_mode(esp_matter_cluster_t *cluster, uint8_t value); -/** Array */ -esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count); +/** cluster: door lock */ +esp_matter_attribute_t *esp_matter_attribute_create_lock_state(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_lock_type(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_actuator_enabled(esp_matter_cluster_t *cluster, bool value); +esp_matter_attribute_t *esp_matter_attribute_create_auto_relock_time(esp_matter_cluster_t *cluster, uint32_t value); +esp_matter_attribute_t *esp_matter_attribute_create_operating_mode(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_supported_operating_modes(esp_matter_cluster_t *cluster, + uint16_t value); -/** Attribute update - * - * This API updates the attribute value - */ -esp_err_t esp_matter_attribute_update(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val); +/** cluster: bridged device basic */ +esp_matter_attribute_t *esp_matter_attribute_create_bridged_device_basic_node_label(esp_matter_cluster_t *cluster, + char *value, uint16_t length); +esp_matter_attribute_t *esp_matter_attribute_create_reachable(esp_matter_cluster_t *cluster, bool value); -/** Attribute value print - * - * This API prints the attribute value according to the type - */ -void esp_matter_attribute_val_print(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val); +/** cluster: fixed label */ +esp_matter_attribute_t *esp_matter_attribute_create_label_list(esp_matter_cluster_t *cluster, uint8_t *value, + uint16_t length, uint16_t count); + +/** cluster: switch */ +esp_matter_attribute_t *esp_matter_attribute_create_number_of_positions(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_current_position(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_multi_press_max(esp_matter_cluster_t *cluster, uint8_t value); + +/** cluster: temperature measurement */ +esp_matter_attribute_t *esp_matter_attribute_create_temperature_measured_value(esp_matter_cluster_t *cluster, + int16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_temperature_min_measured_value(esp_matter_cluster_t *cluster, + int16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_temperature_max_measured_value(esp_matter_cluster_t *cluster, + int16_t value); diff --git a/components/esp_matter/esp_matter_attribute_utils.cpp b/components/esp_matter/esp_matter_attribute_utils.cpp new file mode 100644 index 000000000..72e18ad61 --- /dev/null +++ b/components/esp_matter/esp_matter_attribute_utils.cpp @@ -0,0 +1,1092 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include + +#include +#include + +using chip::AttributeId; +using chip::ClusterId; +using chip::EndpointId; +using chip::Protocols::InteractionModel::Status; + +static const char *TAG = "esp_matter_attribute"; + +static esp_matter_attribute_callback_t attribute_callback = NULL; +static void *attribute_callback_priv_data = NULL; + +static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type); + +static esp_err_t esp_matter_attribute_console_handler(int argc, char **argv) +{ + if (argc == 5 && strncmp(argv[0], "set", sizeof("set")) == 0) { + int endpoint_id = strtol((const char *)&argv[1][2], NULL, 16); + int cluster_id = strtol((const char *)&argv[2][2], NULL, 16); + int attribute_id = strtol((const char *)&argv[3][2], NULL, 16); + + /* Get type from matter_attribute */ + const EmberAfAttributeMetadata *matter_attribute = emberAfLocateAttributeMetadata(endpoint_id, cluster_id, + attribute_id, ESP_MATTER_CLUSTER_FLAG_SERVER); + if (!matter_attribute) { + ESP_LOGE(TAG, "Matter attribute not found"); + return ESP_ERR_INVALID_ARG; + } + + /* Use the type to create the val and then update te attribute */ + esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType); + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) { + bool value = atoi(argv[4]); + val = esp_matter_bool(value); + } else if (type == ESP_MATTER_VAL_TYPE_INT8) { + int8_t value = atoi(argv[4]); + val = esp_matter_int8(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT8) { + uint8_t value = atoi(argv[4]); + val = esp_matter_uint8(value); + } else if (type == ESP_MATTER_VAL_TYPE_INT16) { + int16_t value = atoi(argv[4]); + val = esp_matter_int16(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT16) { + uint16_t value = atoi(argv[4]); + val = esp_matter_uint16(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT32) { + uint32_t value = atoi(argv[4]); + val = esp_matter_uint32(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT64) { + uint64_t value = atoi(argv[4]); + val = esp_matter_uint64(value); + } else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { + char *value = argv[4]; + val = esp_matter_char_str(value, strlen(value)); + } else { + ESP_LOGE(TAG, "Type not handled: %d", type); + return ESP_ERR_INVALID_ARG; + } + esp_matter_attribute_update(endpoint_id, cluster_id, attribute_id, &val); + } else if (argc == 4 && strncmp(argv[0], "get", sizeof("get")) == 0) { + int endpoint_id = strtol((const char *)&argv[1][2], NULL, 16); + int cluster_id = strtol((const char *)&argv[2][2], NULL, 16); + int attribute_id = strtol((const char *)&argv[3][2], NULL, 16); + + /* Get type from matter_attribute */ + const EmberAfAttributeMetadata *matter_attribute = emberAfLocateAttributeMetadata(endpoint_id, cluster_id, + attribute_id, ESP_MATTER_CLUSTER_FLAG_SERVER); + if (!matter_attribute) { + ESP_LOGE(TAG, "Matter attribute not found"); + return ESP_ERR_INVALID_ARG; + } + + /* Use the type to read the raw value and then print */ + esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType); + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) { + bool value = false; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_bool(value); + } else if (type == ESP_MATTER_VAL_TYPE_INT8) { + int8_t value = 0; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_int8(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT8) { + uint8_t value = 0; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_uint8(value); + } else if (type == ESP_MATTER_VAL_TYPE_INT16) { + int16_t value = 0; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_int16(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT16) { + uint16_t value = 0; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_uint16(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT32) { + uint32_t value = 0; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_uint32(value); + } else if (type == ESP_MATTER_VAL_TYPE_UINT64) { + uint64_t value = 0; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_uint64(value); + } else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { + /* Get raw value */ + char value[256] = {0}; /* It can go upto 256 since only 1 byte (first) is used for size */ + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + /* Get val from raw value */ + val = esp_matter_char_str(NULL, 0); + int data_size_len = val.val.a.t - val.val.a.s; + int data_count = 0; + memcpy(&data_count, &value[0], data_size_len); + val = esp_matter_char_str((char *)(value + data_size_len), data_count); + } else { + ESP_LOGE(TAG, "Type not handled: %d", type); + return ESP_ERR_INVALID_ARG; + } + esp_matter_attribute_val_print(endpoint_id, cluster_id, attribute_id, &val); + } else { + ESP_LOGE(TAG, "Incorrect arguments"); + return ESP_ERR_INVALID_ARG; + } + return ESP_OK; +} + +static void esp_matter_attribute_register_commands() +{ + static bool init_done = false; + if (init_done) { + return; + } + esp_matter_console_command_t command = { + .name = "attribute", + .description = "This can be used to simulate on-device control. " + "Usage: matter esp attribute [value]. " + "Example1: matter esp attribute set 0x0001 0x0006 0x0000 1. " + "Example2: matter esp attribute get 0x0001 0x0006 0x0000.", + .handler = esp_matter_attribute_console_handler, + }; + esp_matter_console_add_command(&command); + init_done = true; +} + +esp_matter_attr_val_t esp_matter_invalid(void *val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_INVALID, + .val = { + .p = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_bool(bool val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_BOOLEAN, + .val = { + .b = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_int(int val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_INTEGER, + .val = { + .i = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_float(float val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_FLOAT, + .val = { + .f = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_int8(int8_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_INT8, + .val = { + .i8 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_uint8(uint8_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_UINT8, + .val = { + .u8 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_int16(int16_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_INT16, + .val = { + .i16 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_uint16(uint16_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_UINT16, + .val = { + .u16 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_uint32(uint32_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_UINT32, + .val = { + .u32 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_uint64(uint64_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_UINT64, + .val = { + .u64 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_enum8(uint8_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_ENUM8, + .val = { + .u8 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_bitmap8(uint8_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_BITMAP8, + .val = { + .u8 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_BITMAP16, + .val = { + .u16 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_BITMAP32, + .val = { + .u32 = val, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size) +{ + uint16_t data_size_len = 1; /* Number of bytes used to store the length */ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_CHAR_STRING, + .val = { + .a = { + .b = (uint8_t *)val, + .s = data_size, + .n = data_size, + .t = (uint16_t)(data_size + data_size_len), + }, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size) +{ + uint16_t data_size_len = 1; /* Number of bytes used to store the length */ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_OCTET_STRING, + .val = { + .a = { + .b = val, + .s = data_size, + .n = data_size, + .t = (uint16_t)(data_size + data_size_len), + }, + }, + }; + return attr_val; +} + +esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count) +{ + uint16_t data_size_len = 2; /* Number of bytes used to store the length */ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_ARRAY, + .val = { + .a = { + .b = val, + .s = data_size, + .n = count, + .t = (uint16_t)(data_size + data_size_len), + }, + }, + }; + return attr_val; +} + +static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type) +{ + switch(attribute_type) { + case ZCL_BOOLEAN_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_BOOLEAN; + break; + + case ZCL_SINGLE_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_FLOAT; + break; + + case ZCL_ARRAY_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_ARRAY; + break; + + case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_CHAR_STRING; + break; + + case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_OCTET_STRING; + break; + + case ZCL_INT8S_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_INT8; + break; + + case ZCL_INT8U_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_UINT8; + break; + + case ZCL_INT16S_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_INT16; + break; + + case ZCL_INT16U_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_UINT16; + break; + + case ZCL_INT32U_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_UINT32; + break; + + case ZCL_INT64U_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_UINT64; + break; + + case ZCL_ENUM8_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_ENUM8; + break; + + case ZCL_BITMAP8_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_BITMAP8; + break; + + case ZCL_BITMAP16_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_BITMAP16; + break; + + case ZCL_BITMAP32_ATTRIBUTE_TYPE: + return ESP_MATTER_VAL_TYPE_BITMAP32; + break; + + default: + return ESP_MATTER_VAL_TYPE_INVALID; + break; + } + return ESP_MATTER_VAL_TYPE_INVALID; +} + +esp_err_t esp_matter_attribute_get_type_and_val_default(esp_matter_attr_val_t *val, + EmberAfAttributeType *attribute_type, uint16_t *attribute_size, + EmberAfDefaultOrMinMaxAttributeValue *default_value) +{ + switch (val->type) { + case ESP_MATTER_VAL_TYPE_BOOLEAN: + *attribute_type = ZCL_BOOLEAN_ATTRIBUTE_TYPE; + *attribute_size = sizeof(bool); + *default_value = (uint16_t)val->val.b; + break; + + case ESP_MATTER_VAL_TYPE_INTEGER: + *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint16_t); + *default_value = (uint16_t)val->val.i; + break; + + case ESP_MATTER_VAL_TYPE_FLOAT: + *attribute_type = ZCL_SINGLE_ATTRIBUTE_TYPE; + *attribute_size = sizeof(float); + *default_value = (uint8_t *)&val->val.f; + break; + + case ESP_MATTER_VAL_TYPE_ARRAY: + *attribute_type = ZCL_ARRAY_ATTRIBUTE_TYPE; + *attribute_size = val->val.a.t; + *default_value = (uint8_t *)val->val.a.b; + break; + + case ESP_MATTER_VAL_TYPE_CHAR_STRING: + *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; + *attribute_size = val->val.a.t; + *default_value = (uint8_t *)val->val.a.b; + break; + + case ESP_MATTER_VAL_TYPE_OCTET_STRING: + *attribute_type = ZCL_OCTET_STRING_ATTRIBUTE_TYPE; + *attribute_size = val->val.a.t; + *default_value = (uint8_t *)val->val.a.b; + break; + + case ESP_MATTER_VAL_TYPE_INT8: + *attribute_type = ZCL_INT8S_ATTRIBUTE_TYPE; + *attribute_size = sizeof(int8_t); + *default_value = (uint16_t)val->val.i8; + break; + + case ESP_MATTER_VAL_TYPE_UINT8: + *attribute_type = ZCL_INT8U_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint8_t); + *default_value = (uint16_t)val->val.u8; + break; + + case ESP_MATTER_VAL_TYPE_INT16: + *attribute_type = ZCL_INT16S_ATTRIBUTE_TYPE; + *attribute_size = sizeof(int16_t); + *default_value = (int16_t)val->val.i16; + break; + + case ESP_MATTER_VAL_TYPE_UINT16: + *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint16_t); + *default_value = (uint16_t)val->val.u16; + break; + + case ESP_MATTER_VAL_TYPE_UINT32: + *attribute_type = ZCL_INT32U_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint32_t); + *default_value = (uint8_t *)&val->val.u32; + break; + + case ESP_MATTER_VAL_TYPE_UINT64: + *attribute_type = ZCL_INT64U_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint64_t); + *default_value = (uint8_t *)&val->val.u64; + break; + + case ESP_MATTER_VAL_TYPE_ENUM8: + *attribute_type = ZCL_ENUM8_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint8_t); + *default_value = (uint16_t)val->val.u8; + break; + + case ESP_MATTER_VAL_TYPE_BITMAP8: + *attribute_type = ZCL_BITMAP8_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint8_t); + *default_value = (uint16_t)val->val.u8; + break; + + case ESP_MATTER_VAL_TYPE_BITMAP16: + *attribute_type = ZCL_BITMAP16_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint16_t); + *default_value = (uint16_t)val->val.u16; + break; + + case ESP_MATTER_VAL_TYPE_BITMAP32: + *attribute_type = ZCL_BITMAP32_ATTRIBUTE_TYPE; + *attribute_size = sizeof(uint32_t); + *default_value = (uint8_t *)&val->val.u32; + break; + + default: + ESP_LOGE(TAG, "esp_matter_attr_val_type_t not handled: %d", val->type); + break; + } + + return ESP_OK; +} + +static esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, + uint16_t *attribute_size, uint8_t *value) +{ + switch (val->type) { + case ESP_MATTER_VAL_TYPE_BOOLEAN: + if (attribute_type) { + *attribute_type = ZCL_BOOLEAN_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(bool); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.b, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_INTEGER: + if (attribute_type) { + *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint16_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.i, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_FLOAT: + if (attribute_type) { + *attribute_type = ZCL_SINGLE_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(float); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.f, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_ARRAY: + if (attribute_type) { + *attribute_type = ZCL_ARRAY_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = val->val.a.t; + } + if (value) { + int data_size_len = val->val.a.t - val->val.a.s; + memcpy(value, (uint8_t *)&val->val.a.s, data_size_len); + memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len)); + } + break; + + case ESP_MATTER_VAL_TYPE_CHAR_STRING: + if (attribute_type) { + *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = val->val.a.t; + } + if (value) { + int data_size_len = val->val.a.t - val->val.a.s; + memcpy(value, (uint8_t *)&val->val.a.s, data_size_len); + memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len)); + } + break; + + case ESP_MATTER_VAL_TYPE_OCTET_STRING: + if (attribute_type) { + *attribute_type = ZCL_OCTET_STRING_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = val->val.a.t; + } + if (value) { + int data_size_len = val->val.a.t - val->val.a.s; + memcpy(value, (uint8_t *)&val->val.a.s, data_size_len); + memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len)); + } + break; + + case ESP_MATTER_VAL_TYPE_INT8: + if (attribute_type) { + *attribute_type = ZCL_INT8S_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(int8_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.i8, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_UINT8: + if (attribute_type) { + *attribute_type = ZCL_INT8U_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint8_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_INT16: + if (attribute_type) { + *attribute_type = ZCL_INT16S_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(int16_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.i16, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_UINT16: + if (attribute_type) { + *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint16_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u16, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_UINT32: + if (attribute_type) { + *attribute_type = ZCL_INT32U_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint32_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u32, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_UINT64: + if (attribute_type) { + *attribute_type = ZCL_INT64U_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint64_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u64, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_ENUM8: + if (attribute_type) { + *attribute_type = ZCL_ENUM8_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint8_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_BITMAP8: + if (attribute_type) { + *attribute_type = ZCL_BITMAP8_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint8_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_BITMAP16: + if (attribute_type) { + *attribute_type = ZCL_BITMAP16_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint16_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u16, *attribute_size); + } + break; + + case ESP_MATTER_VAL_TYPE_BITMAP32: + if (attribute_type) { + *attribute_type = ZCL_BITMAP32_ATTRIBUTE_TYPE; + } + if (attribute_size) { + *attribute_size = sizeof(uint32_t); + } + if (value) { + memcpy(value, (uint8_t *)&val->val.u32, *attribute_size); + } + break; + + default: + ESP_LOGE(TAG, "esp_matter_attr_val_type_t not handled: %d", val->type); + break; + } + + return ESP_OK; +} + +static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttributeType attribute_type, + uint16_t attribute_size, uint8_t *value) +{ + switch (attribute_type) { + case ZCL_BOOLEAN_ATTRIBUTE_TYPE: + { + bool attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(bool)); + *val = esp_matter_bool(attribute_value); + break; + } + + case ZCL_ARRAY_ATTRIBUTE_TYPE: + { + *val = esp_matter_array(NULL, 0, 0); + int data_size_len = val->val.a.t - val->val.a.s; + int data_count = 0; + memcpy(&data_count, &value[0], data_size_len); + *val = esp_matter_array((value + data_size_len), attribute_size, data_count); + break; + } + + case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: + { + *val = esp_matter_char_str(NULL, 0); + int data_size_len = val->val.a.t - val->val.a.s; + int data_count = 0; + memcpy(&data_count, &value[0], data_size_len); + *val = esp_matter_char_str((char *)(value + data_size_len), data_count); + break; + } + + case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: + { + *val = esp_matter_octet_str(NULL, 0); + int data_size_len = val->val.a.t - val->val.a.s; + int data_count = 0; + memcpy(&data_count, &value[0], data_size_len); + *val = esp_matter_octet_str((value + data_size_len), data_count); + break; + } + + case ZCL_INT8S_ATTRIBUTE_TYPE: + { + int8_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(int8_t)); + *val = esp_matter_int8(attribute_value); + break; + } + + case ZCL_INT8U_ATTRIBUTE_TYPE: + { + uint8_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); + *val = esp_matter_uint8(attribute_value); + break; + } + + case ZCL_INT16S_ATTRIBUTE_TYPE: + { + int16_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(int16_t)); + *val = esp_matter_int16(attribute_value); + break; + } + + case ZCL_INT16U_ATTRIBUTE_TYPE: + { + uint16_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(uint16_t)); + *val = esp_matter_uint16(attribute_value); + break; + } + + case ZCL_INT32U_ATTRIBUTE_TYPE: + { + uint32_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(uint32_t)); + *val = esp_matter_uint32(attribute_value); + break; + } + + case ZCL_INT64U_ATTRIBUTE_TYPE: + { + uint64_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(uint64_t)); + *val = esp_matter_uint64(attribute_value); + break; + } + + case ZCL_ENUM8_ATTRIBUTE_TYPE: + { + uint8_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); + *val = esp_matter_enum8(attribute_value); + break; + } + + case ZCL_BITMAP8_ATTRIBUTE_TYPE: + { + uint8_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); + *val = esp_matter_bitmap8(attribute_value); + break; + } + + case ZCL_BITMAP16_ATTRIBUTE_TYPE: + { + uint16_t attribute_value = 0; + memcpy((uint8_t *)&attribute_value, value, sizeof(uint16_t)); + *val = esp_matter_bitmap16(attribute_value); + break; + } + + default: + *val = esp_matter_invalid(NULL); + break; + } + + return ESP_OK; +} + +void esp_matter_attribute_val_print(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val) +{ + if (val->type == ESP_MATTER_VAL_TYPE_BOOLEAN) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, + cluster_id, attribute_id, val->val.b); + } else if (val->type == ESP_MATTER_VAL_TYPE_INTEGER) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, + cluster_id, attribute_id, val->val.i); + } else if (val->type == ESP_MATTER_VAL_TYPE_FLOAT) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %f **********", endpoint_id, + cluster_id, attribute_id, val->val.f); + } else if (val->type == ESP_MATTER_VAL_TYPE_UINT8 || val->type == ESP_MATTER_VAL_TYPE_BITMAP8) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, + cluster_id, attribute_id, val->val.u8); + } else if (val->type == ESP_MATTER_VAL_TYPE_INT16) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, + cluster_id, attribute_id, val->val.i16); + } else if (val->type == ESP_MATTER_VAL_TYPE_UINT16) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, + cluster_id, attribute_id, val->val.u16); + } else if (val->type == ESP_MATTER_VAL_TYPE_UINT32) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, + cluster_id, attribute_id, val->val.u32); + } else if (val->type == ESP_MATTER_VAL_TYPE_UINT64) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %lld **********", endpoint_id, + cluster_id, attribute_id, val->val.u64); + } else if (val->type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %.*s **********", endpoint_id, + cluster_id, attribute_id, val->val.a.s, val->val.a.b); + } else { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is **********", + endpoint_id, cluster_id, attribute_id, val->type); + } +} + +esp_err_t esp_matter_attribute_callback_set(esp_matter_attribute_callback_t callback, void *priv_data) +{ + attribute_callback = callback; + attribute_callback_priv_data = priv_data; + + /* Other initialisations */ + esp_matter_attribute_register_commands(); + return ESP_OK; +} + +esp_err_t esp_matter_attribute_get_val_raw(int endpoint_id, int cluster_id, int attribute_id, uint8_t *value, + uint16_t attribute_size) +{ + /* Take lock if not already taken */ + esp_matter_lock_status_t lock_status = esp_matter_chip_stack_lock(portMAX_DELAY); + if (lock_status == ESP_MATTER_LOCK_FAILED) { + ESP_LOGE(TAG, "Could not get task context"); + return ESP_FAIL; + } + + EmberAfStatus status = emberAfReadServerAttribute(endpoint_id, cluster_id, attribute_id, value, attribute_size); + if (status != EMBER_ZCL_STATUS_SUCCESS) { + ESP_LOGE(TAG, "Error getting raw value from matter: 0x%x", status); + if (lock_status == ESP_MATTER_LOCK_SUCCESS) { + esp_matter_chip_stack_unlock(); + } + return ESP_FAIL; + } + if (lock_status == ESP_MATTER_LOCK_SUCCESS) { + esp_matter_chip_stack_unlock(); + } + return ESP_OK; +} + +esp_err_t esp_matter_attribute_update(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val) +{ + /* Take lock if not already taken */ + esp_matter_lock_status_t lock_status = esp_matter_chip_stack_lock(portMAX_DELAY); + if (lock_status == ESP_MATTER_LOCK_FAILED) { + ESP_LOGE(TAG, "Could not get task context"); + return ESP_FAIL; + } + + /* Get size */ + EmberAfAttributeType attribute_type = 0; + uint16_t attribute_size = 0; + get_data_from_attr_val(val, &attribute_type, &attribute_size, NULL); + + /* Get value */ + uint8_t *value = (uint8_t *)calloc(1, attribute_size); + if (!value) { + ESP_LOGE(TAG, "Could not allocate value buffer"); + if (lock_status == ESP_MATTER_LOCK_SUCCESS) { + esp_matter_chip_stack_unlock(); + } + return ESP_ERR_NO_MEM; + } + get_data_from_attr_val(val, &attribute_type, &attribute_size, value); + + /* Update matter */ + EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; + if (emberAfContainsServer(endpoint_id, cluster_id)) { + status = emberAfWriteServerAttribute(endpoint_id, cluster_id, attribute_id, value, attribute_type); + if (status != EMBER_ZCL_STATUS_SUCCESS) { + ESP_LOGE(TAG, "Error updating attribute to matter"); + free(value); + if (lock_status == ESP_MATTER_LOCK_SUCCESS) { + esp_matter_chip_stack_unlock(); + } + return ESP_FAIL; + } + } + free(value); + if (lock_status == ESP_MATTER_LOCK_SUCCESS) { + esp_matter_chip_stack_unlock(); + } + return ESP_OK; +} + +Status MatterPreAttributeChangeCallback(const chip::app::ConcreteAttributePath &path, uint8_t mask, uint8_t type, + uint16_t size, uint8_t *value) +{ + int endpoint_id = path.mEndpointId; + int cluster_id = path.mClusterId; + int attribute_id = path.mAttributeId; + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + get_attr_val_from_data(&val, type, size, value); + + /* Print */ + esp_matter_attribute_val_print(endpoint_id, cluster_id, attribute_id, &val); + + /* Callback to application */ + if (attribute_callback) { + esp_err_t err = attribute_callback(ESP_MATTER_CALLBACK_TYPE_PRE_ATTRIBUTE, endpoint_id, cluster_id, + attribute_id, &val, attribute_callback_priv_data); + if (err != ESP_OK) { + return Status::Failure; + } + } + return Status::Success; +} + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &path, uint8_t mask, uint8_t type, + uint16_t size, uint8_t *value) +{ + int endpoint_id = path.mEndpointId; + int cluster_id = path.mClusterId; + int attribute_id = path.mAttributeId; + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + get_attr_val_from_data(&val, type, size, value); + + /* Callback to application */ + if (attribute_callback) { + attribute_callback(ESP_MATTER_CALLBACK_TYPE_POST_ATTRIBUTE, endpoint_id, cluster_id, attribute_id, &val, + attribute_callback_priv_data); + } +} + +EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint_id, ClusterId cluster_id, + const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer, + uint16_t max_read_length) +{ + /* Get value */ + int attribute_id = matter_attribute->attributeId; + esp_matter_node_t *node = esp_matter_node_get(); + if (!node) { + return EMBER_ZCL_STATUS_FAILURE; + } + esp_matter_endpoint_t *endpoint = esp_matter_endpoint_get(node, endpoint_id); + esp_matter_cluster_t *cluster = esp_matter_cluster_get(endpoint, cluster_id); + esp_matter_attribute_t *attribute = esp_matter_attribute_get(cluster, attribute_id); + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + esp_matter_attribute_get_val(attribute, &val); + + /* Print */ + esp_matter_attribute_val_print(endpoint_id, cluster_id, attribute_id, &val); + + /* Get size */ + uint16_t attribute_size = 0; + get_data_from_attr_val(&val, NULL, &attribute_size, NULL); + if (attribute_size > max_read_length) { + ESP_LOGE(TAG, "Insufficient space for reading attribute: required: %d, max: %d", attribute_size, + max_read_length); + return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE; + } + + /* Assign value */ + get_data_from_attr_val(&val, NULL, &attribute_size, buffer); + return EMBER_ZCL_STATUS_SUCCESS; +} + +EmberAfStatus emberAfExternalAttributeWriteCallback(EndpointId endpoint_id, ClusterId cluster_id, + const EmberAfAttributeMetadata *matter_attribute, uint8_t *buffer) +{ + /* Get value */ + int attribute_id = matter_attribute->attributeId; + esp_matter_node_t *node = esp_matter_node_get(); + if (!node) { + return EMBER_ZCL_STATUS_FAILURE; + } + esp_matter_endpoint_t *endpoint = esp_matter_endpoint_get(node, endpoint_id); + esp_matter_cluster_t *cluster = esp_matter_cluster_get(endpoint, cluster_id); + esp_matter_attribute_t *attribute = esp_matter_attribute_get(cluster, attribute_id); + + /* Get val */ + /* This creates a new variable val, and stores the new attribute value in the new variable. + The value in esp-matter data model is updated only when esp_matter_attribute_set_val() is called */ + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + get_attr_val_from_data(&val, matter_attribute->attributeType, matter_attribute->size, buffer); + + /* Update val */ + esp_matter_attribute_set_val(attribute, &val); + return EMBER_ZCL_STATUS_SUCCESS; +} diff --git a/components/esp_matter/esp_matter_attribute_utils.h b/components/esp_matter/esp_matter_attribute_utils.h new file mode 100644 index 000000000..4f88469d0 --- /dev/null +++ b/components/esp_matter/esp_matter_attribute_utils.h @@ -0,0 +1,166 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include + +#define REMAP_TO_RANGE(value, from, to) ((value * to) / from) + +/** ESP Matter Attribute Value type */ +typedef enum { + /** Invalid */ + ESP_MATTER_VAL_TYPE_INVALID = 0, + /** Boolean */ + ESP_MATTER_VAL_TYPE_BOOLEAN, + /** Integer. Mapped to a 32 bit signed integer */ + ESP_MATTER_VAL_TYPE_INTEGER, + /** Floating point number */ + ESP_MATTER_VAL_TYPE_FLOAT, + /** Array Eg. [1,2,3] */ + ESP_MATTER_VAL_TYPE_ARRAY, + /** Char String Eg. "123" */ + ESP_MATTER_VAL_TYPE_CHAR_STRING, + /** Octet String Eg. [0x01, 0x20] */ + ESP_MATTER_VAL_TYPE_OCTET_STRING, + /** 8 bit signed integer */ + ESP_MATTER_VAL_TYPE_INT8, + /** 8 bit unsigned integer */ + ESP_MATTER_VAL_TYPE_UINT8, + /** 16 bit signed integer */ + ESP_MATTER_VAL_TYPE_INT16, + /** 16 bit unsigned integer */ + ESP_MATTER_VAL_TYPE_UINT16, + /** 32 bit unsigned integer */ + ESP_MATTER_VAL_TYPE_UINT32, + /** 64 bit unsigned integer */ + ESP_MATTER_VAL_TYPE_UINT64, + /** 8 bit enum */ + ESP_MATTER_VAL_TYPE_ENUM8, + /** 8 bit bitmap */ + ESP_MATTER_VAL_TYPE_BITMAP8, + /** 16 bit bitmap */ + ESP_MATTER_VAL_TYPE_BITMAP16, + /** 32 bit bitmap */ + ESP_MATTER_VAL_TYPE_BITMAP32, +} esp_matter_val_type_t; + +/* ESP Matter Value */ +typedef union { + /** Boolean */ + bool b; + /** Integer */ + int i; + /** Float */ + float f; + /** 8 bit signed integer */ + int8_t i8; + /** 8 bit unsigned integer */ + uint8_t u8; + /** 16 bit signed integer */ + int16_t i16; + /** 16 bit unsigned integer */ + uint16_t u16; + /** 32 bit unsigned integer */ + uint32_t u32; + /** 64 bit unsigned integer */ + uint64_t u64; + /** Array */ + struct { + /** Buffer */ + uint8_t *b; + /** Data size */ + uint16_t s; + /** Data count */ + uint16_t n; + /** Total size */ + uint16_t t; + } a; + /** Pointer */ + void *p; +} esp_matter_val_t; + +/* ESP Matter Attribute Value */ +typedef struct { + /** Type of Value */ + esp_matter_val_type_t type; + /** Actual value. Depends on the type */ + esp_matter_val_t val; +} esp_matter_attr_val_t; + +/*** Attribute val APIs ***/ +/** Invalid */ +esp_matter_attr_val_t esp_matter_invalid(void *val); + +/** Boolean */ +esp_matter_attr_val_t esp_matter_bool(bool val); + +/** Integer */ +esp_matter_attr_val_t esp_matter_int(int val); + +/** Float */ +esp_matter_attr_val_t esp_matter_float(float val); + +/** 8 bit integer */ +esp_matter_attr_val_t esp_matter_int8(int8_t val); + +/** 8 bit unsigned integer */ +esp_matter_attr_val_t esp_matter_uint8(uint8_t val); + +/** 16 bit signed integer */ +esp_matter_attr_val_t esp_matter_int16(int16_t val); + +/** 16 bit unsigned integer */ +esp_matter_attr_val_t esp_matter_uint16(uint16_t val); + +/** 32 bit unsigned integer */ +esp_matter_attr_val_t esp_matter_uint32(uint32_t val); + +/** 64 bit unsigned integer */ +esp_matter_attr_val_t esp_matter_uint64(uint64_t val); + +/** 8 bit enum */ +esp_matter_attr_val_t esp_matter_enum8(uint8_t val); + +/** 8 bit bitmap */ +esp_matter_attr_val_t esp_matter_bitmap8(uint8_t val); + +/** 16 bit bitmap */ +esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val); + +/** 32 bit bitmap */ +esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val); + +/** Character string */ +esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size); + +/** Octet string */ +esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size); + +/** Array */ +esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count); + +/** Attribute update + * + * This API updates the attribute value + */ +esp_err_t esp_matter_attribute_update(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val); + +/** Attribute value print + * + * This API prints the attribute value according to the type + */ +void esp_matter_attribute_val_print(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t *val); diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index bc2bba43e..553f753ab 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -152,9 +153,7 @@ void esp_matter_cluster_plugin_init_callback_common() } } -esp_matter_cluster_t *esp_matter_cluster_create_descriptor(esp_matter_endpoint_t *endpoint, - esp_matter_cluster_descriptor_config_t *config, - uint8_t flags) +esp_matter_cluster_t *esp_matter_cluster_create_descriptor(esp_matter_endpoint_t *endpoint, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_DESCRIPTOR_CLUSTER_ID, flags); if (!cluster) { @@ -171,23 +170,17 @@ esp_matter_cluster_t *esp_matter_cluster_create_descriptor(esp_matter_endpoint_t esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterDescriptorPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_DEVICE_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->device_type_list, sizeof(config->device_type_list), 0)); - esp_matter_attribute_create(cluster, ZCL_SERVER_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->server_list, sizeof(config->server_list), 0)); - esp_matter_attribute_create(cluster, ZCL_CLIENT_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->client_list, sizeof(config->client_list), 0)); - esp_matter_attribute_create(cluster, ZCL_PARTS_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->parts_list, sizeof(config->parts_list), 0)); + /* Attributes managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, 0); + esp_matter_attribute_create_device_list(cluster, NULL, 0, 0); + esp_matter_attribute_create_server_list(cluster, NULL, 0, 0); + esp_matter_attribute_create_client_list(cluster, NULL, 0, 0); + esp_matter_attribute_create_parts_list(cluster, NULL, 0, 0); return cluster; } -esp_matter_cluster_t *esp_matter_cluster_create_access_control(esp_matter_endpoint_t *endpoint, - esp_matter_cluster_access_control_config_t *config, - uint8_t flags) +esp_matter_cluster_t *esp_matter_cluster_create_access_control(esp_matter_endpoint_t *endpoint, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_ACCESS_CONTROL_CLUSTER_ID, ESP_MATTER_CLUSTER_FLAG_SERVER); @@ -204,13 +197,10 @@ esp_matter_cluster_t *esp_matter_cluster_create_access_control(esp_matter_endpoi esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterAccessControlPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_ACL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->acl, sizeof(config->acl), 0)); - esp_matter_attribute_create(cluster, ZCL_EXTENSION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->extension, sizeof(config->extension), 0)); - + /* Attributes managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, 0); + esp_matter_attribute_create_acl(cluster, NULL, 0, 0); + esp_matter_attribute_create_extension(cluster, NULL, 0, 0); return cluster; } @@ -232,34 +222,21 @@ esp_matter_cluster_t *esp_matter_cluster_create_basic(esp_matter_endpoint_t *end esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterBasicPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_DATA_MODEL_REVISION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->data_model_revision)); - esp_matter_attribute_create(cluster, ZCL_VENDOR_NAME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->vendor_name, sizeof(config->vendor_name))); - esp_matter_attribute_create(cluster, ZCL_VENDOR_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->vendor_id)); - esp_matter_attribute_create(cluster, ZCL_PRODUCT_NAME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->product_name, sizeof(config->product_name))); - esp_matter_attribute_create(cluster, ZCL_PRODUCT_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->product_id)); - esp_matter_attribute_create(cluster, ZCL_NODE_LABEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->node_label, sizeof(config->node_label))); - esp_matter_attribute_create(cluster, ZCL_LOCATION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->location, sizeof(config->location))); - esp_matter_attribute_create(cluster, ZCL_HARDWARE_VERSION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->hardware_version)); - esp_matter_attribute_create(cluster, ZCL_HARDWARE_VERSION_STRING_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->hardware_version_string, - sizeof(config->hardware_version_string))); - esp_matter_attribute_create(cluster, ZCL_SOFTWARE_VERSION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint32(config->software_version)); - esp_matter_attribute_create(cluster, ZCL_SOFTWARE_VERSION_STRING_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->software_version_string, - sizeof(config->software_version_string))); - esp_matter_attribute_create(cluster, ZCL_SERIAL_NUMBER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->serial_number, sizeof(config->serial_number))); + /* Attributes managed internally */ + esp_matter_attribute_create_data_model_revision(cluster, 0); + esp_matter_attribute_create_location(cluster, NULL, 0); + esp_matter_attribute_create_vendor_name(cluster, NULL, 0); + esp_matter_attribute_create_vendor_id(cluster, 0); + esp_matter_attribute_create_product_name(cluster, NULL, 0); + esp_matter_attribute_create_product_id(cluster, 0); + esp_matter_attribute_create_hardware_version(cluster, 0); + esp_matter_attribute_create_hardware_version_string(cluster, NULL, 0); + esp_matter_attribute_create_software_version(cluster, 0); + esp_matter_attribute_create_software_version_string(cluster, NULL, 0); + + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_node_label(cluster, config->node_label, sizeof(config->node_label)); return cluster; } @@ -282,13 +259,15 @@ esp_matter_cluster_t *esp_matter_cluster_create_binding(esp_matter_endpoint_t *e if (flags & ESP_MATTER_CLUSTER_FLAG_CLIENT) { esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterBindingPluginClientInitCallback); } + /* Extra initialization */ esp_matter_binding_init(); - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_BINDING_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, - esp_matter_array(config->binding_list, sizeof(config->binding_list), 0)); + /* Attributes managed internally */ + esp_matter_attribute_create_binding(cluster, NULL, 0, 0); + + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); return cluster; } @@ -314,9 +293,10 @@ esp_matter_cluster_t *esp_matter_cluster_create_ota_provider(esp_matter_endpoint MatterOtaSoftwareUpdateProviderPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + /* Commands */ esp_matter_command_create_query_image(cluster); esp_matter_command_create_query_image_response(cluster); esp_matter_command_create_apply_update_request(cluster); @@ -347,18 +327,16 @@ esp_matter_cluster_t *esp_matter_cluster_create_ota_requestor(esp_matter_endpoin MatterOtaSoftwareUpdateRequestorPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_DEFAULT_OTA_PROVIDERS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_octet_str(config->default_ota_providers, - sizeof(config->default_ota_providers))); - esp_matter_attribute_create(cluster, ZCL_UPDATE_POSSIBLE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bool(config->update_possible)); - esp_matter_attribute_create(cluster, ZCL_UPDATE_STATE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->update_state)); - esp_matter_attribute_create(cluster, ZCL_UPDATE_STATE_PROGRESS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->update_state_progress)); + /* Attributes managed internally */ + esp_matter_attribute_create_default_ota_providers(cluster, NULL, 0); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_update_possible(cluster, config->update_possible); + esp_matter_attribute_create_update_state(cluster, config->update_state); + esp_matter_attribute_create_update_state_progress(cluster, config->update_state_progress); + + /* Commands */ esp_matter_command_create_announce_ota_provider(cluster); return cluster; @@ -383,18 +361,16 @@ esp_matter_cluster_t *esp_matter_cluster_create_general_commissioning(esp_matter esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterGeneralCommissioningPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_BREADCRUMB_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint64(config->breadcrumb)); - esp_matter_attribute_create(cluster, ZCL_BASICCOMMISSIONINGINFO_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->basic_commissioning_info, - sizeof(config->basic_commissioning_info), 0)); - esp_matter_attribute_create(cluster, ZCL_REGULATORYCONFIG_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->regulatory_config)); - esp_matter_attribute_create(cluster, ZCL_LOCATIONCAPABILITY_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->location_capability)); + /* Attributes managed internally */ + esp_matter_attribute_create_regulatory_config(cluster, 0); + esp_matter_attribute_create_location_capability(cluster, 0); + esp_matter_attribute_create_basic_commissioning_info(cluster, NULL, 0, 0); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_breadcrumb(cluster, config->breadcrumb); + + /* Commands */ esp_matter_command_create_arm_fail_safe(cluster); esp_matter_command_create_arm_fail_safe_response(cluster); esp_matter_command_create_set_regulatory_config(cluster); @@ -424,27 +400,21 @@ esp_matter_cluster_t *esp_matter_cluster_create_network_commissioning(esp_matter esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterNetworkCommissioningPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_FEATURE_MAP_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap32(config->feature_map)); - esp_matter_attribute_create(cluster, ZCL_MAX_NETWORKS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->max_networks)); - esp_matter_attribute_create(cluster, ZCL_NETWORKS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->networks, sizeof(config->networks), 0)); - esp_matter_attribute_create(cluster, ZCL_SCAN_MAX_TIME_SECONDS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->scan_max_time_seconds)); - esp_matter_attribute_create(cluster, ZCL_CONNECT_MAX_TIME_SECONDS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->connect_max_time_seconds)); - esp_matter_attribute_create(cluster, ZCL_INTERFACE_ENABLED_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bool(config->interface_enabled)); - esp_matter_attribute_create(cluster, ZCL_LAST_NETWORKING_STATUS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->last_networking_status)); - esp_matter_attribute_create(cluster, ZCL_LAST_NETWORK_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_octet_str(config->last_network_id, sizeof(config->last_network_id))); - esp_matter_attribute_create(cluster, ZCL_LAST_CONNECT_ERROR_VALUE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint32(config->last_connect_error_value)); + /* Attributes managed internally */ + esp_matter_attribute_create_max_networks(cluster, 0); + esp_matter_attribute_create_networks(cluster, NULL, 0, 0); + esp_matter_attribute_create_scan_max_time_seconds(cluster, 0); + esp_matter_attribute_create_connect_max_time_seconds(cluster, 0); + esp_matter_attribute_create_interface_enabled(cluster, 0); + esp_matter_attribute_create_last_networking_status(cluster, 0); + esp_matter_attribute_create_last_network_id(cluster, NULL, 0); + esp_matter_attribute_create_last_connect_error_value(cluster, 0); + esp_matter_attribute_create_feature_map(cluster, 0); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + + /* Commands */ esp_matter_command_create_scan_networks(cluster); esp_matter_command_create_scan_networks_response(cluster); esp_matter_command_create_add_or_update_wifi_network(cluster); @@ -477,12 +447,12 @@ esp_matter_cluster_t *esp_matter_cluster_create_general_diagnostics(esp_matter_e esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterGeneralDiagnosticsPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_NETWORK_INTERFACES_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->network_interfaces, sizeof(config->network_interfaces), 0)); - esp_matter_attribute_create(cluster, ZCL_REBOOT_COUNT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->reboot_count)); + /* Attributes managed internally */ + esp_matter_attribute_create_network_interfaces(cluster, NULL, 0, 0); + esp_matter_attribute_create_reboot_count(cluster, 0); + + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); return cluster; } @@ -509,15 +479,15 @@ esp_matter_cluster_t *esp_matter_cluster_create_administrator_commissioning(esp_ MatterAdministratorCommissioningPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_WINDOW_STATUS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->window_status)); - esp_matter_attribute_create(cluster, ZCL_ADMIN_FABRIC_INDEX_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->admin_fabric_index)); - esp_matter_attribute_create(cluster, ZCL_ADMIN_VENDOR_ID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->admin_vendor_id)); + /* Attributes managed internally */ + esp_matter_attribute_create_window_status(cluster, 0); + esp_matter_attribute_create_admin_fabric_index(cluster, 0); + esp_matter_attribute_create_admin_vendor_id(cluster, 0); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + + /* Commands */ esp_matter_command_create_open_commissioning_window(cluster); esp_matter_command_create_open_basic_commissioning_window(cluster); esp_matter_command_create_revoke_commissioning(cluster); @@ -546,22 +516,18 @@ esp_matter_cluster_t *esp_matter_cluster_create_operational_credentials(esp_matt MatterOperationalCredentialsPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_NOCS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->nocs, sizeof(config->nocs), 0)); - esp_matter_attribute_create(cluster, ZCL_FABRICS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->fabrics, sizeof(config->fabrics), 0)); - esp_matter_attribute_create(cluster, ZCL_SUPPORTED_FABRICS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->supported_fabrics)); - esp_matter_attribute_create(cluster, ZCL_COMMISSIONED_FABRICS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->commissioned_fabrics)); - esp_matter_attribute_create(cluster, ZCL_TRUSTED_ROOTS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->trusted_root_certificates, - sizeof(config->trusted_root_certificates), 0)); - esp_matter_attribute_create(cluster, ZCL_CURRENT_FABRIC_INDEX_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->current_fabric_index)); + /* Attributes managed internally */ + esp_matter_attribute_create_nocs(cluster, NULL, 0, 0); + esp_matter_attribute_create_supported_fabrics(cluster, 0); + esp_matter_attribute_create_commissioned_fabrics(cluster, 0); + esp_matter_attribute_create_fabrics(cluster, NULL, 0, 0); + esp_matter_attribute_create_trusted_root_certificates(cluster, NULL, 0, 0); + esp_matter_attribute_create_current_fabric_index(cluster, 0); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + + /* Commands */ esp_matter_command_create_attestation_request(cluster); esp_matter_command_create_attestation_response(cluster); esp_matter_command_create_certificate_chain_request(cluster); @@ -579,9 +545,7 @@ esp_matter_cluster_t *esp_matter_cluster_create_operational_credentials(esp_matt return cluster; } -esp_matter_cluster_t *esp_matter_cluster_create_group_key_management(esp_matter_endpoint_t *endpoint, - esp_matter_cluster_group_key_management_config_t *config, - uint8_t flags) +esp_matter_cluster_t *esp_matter_cluster_create_group_key_management(esp_matter_endpoint_t *endpoint, uint8_t flags) { esp_matter_cluster_t *cluster = esp_matter_cluster_create(endpoint, ZCL_GROUP_KEY_MANAGEMENT_CLUSTER_ID, flags); if (!cluster) { @@ -598,17 +562,14 @@ esp_matter_cluster_t *esp_matter_cluster_create_group_key_management(esp_matter_ esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterGroupKeyManagementPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_GROUP_KEY_MAP_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->group_key_map, sizeof(config->group_key_map), 0)); - esp_matter_attribute_create(cluster, ZCL_GROUP_TABLE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->group_table, sizeof(config->group_table), 0)); - esp_matter_attribute_create(cluster, ZCL_MAX_GROUPS_PER_FABRIC_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->max_groups_per_fabric)); - esp_matter_attribute_create(cluster, ZCL_MAX_GROUP_KEYS_PER_FABRIC_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->max_group_keys_per_fabric)); + /* Attributes managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, 0); + esp_matter_attribute_create_group_key_map(cluster, NULL, 0, 0); + esp_matter_attribute_create_group_table(cluster, NULL, 0, 0); + esp_matter_attribute_create_max_groups_per_fabric(cluster, 0); + esp_matter_attribute_create_max_group_keys_per_fabric(cluster, 0); + /* Commands */ esp_matter_command_create_key_set_write(cluster); esp_matter_command_create_key_set_read(cluster); esp_matter_command_create_key_set_read_response(cluster); @@ -637,13 +598,12 @@ esp_matter_cluster_t *esp_matter_cluster_create_identify(esp_matter_endpoint_t * esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterIdentifyPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->identify_time)); - esp_matter_attribute_create(cluster, ZCL_IDENTIFY_TYPE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->identify_type)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_identify_time(cluster, config->identify_time); + esp_matter_attribute_create_identify_type(cluster, config->identify_type); + /* Commands */ esp_matter_command_create_identify(cluster); esp_matter_command_create_identify_query(cluster); esp_matter_command_create_identify_query_response(cluster); @@ -669,11 +629,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_groups(esp_matter_endpoint_t *en esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterGroupsPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_GROUP_NAME_SUPPORT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->name_support)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_group_name_support(cluster, config->group_name_support); + /* Commands */ esp_matter_command_create_add_group(cluster); esp_matter_command_create_view_group(cluster); esp_matter_command_create_get_group_membership(cluster); @@ -706,19 +666,15 @@ esp_matter_cluster_t *esp_matter_cluster_create_scenes(esp_matter_endpoint_t *en esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterScenesPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_SCENE_COUNT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->scene_count)); - esp_matter_attribute_create(cluster, ZCL_CURRENT_SCENE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->current_scene)); - esp_matter_attribute_create(cluster, ZCL_CURRENT_GROUP_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->current_group)); - esp_matter_attribute_create(cluster, ZCL_SCENE_VALID_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bool(config->scene_valid)); - esp_matter_attribute_create(cluster, ZCL_SCENE_NAME_SUPPORT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->name_support)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_scene_count(cluster, config->scene_count); + esp_matter_attribute_create_current_scene(cluster, config->current_scene); + esp_matter_attribute_create_current_group(cluster, config->current_group); + esp_matter_attribute_create_scene_valid(cluster, config->scene_valid); + esp_matter_attribute_create_scene_name_support(cluster, config->scene_name_support); + /* Commands */ esp_matter_command_create_add_scene(cluster); esp_matter_command_create_view_scene(cluster); esp_matter_command_create_remove_scene(cluster); @@ -754,11 +710,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_on_off(esp_matter_endpoint_t *en esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterOnOffPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_ON_OFF_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bool(config->on_off)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_on_off(cluster, config->on_off); + /* Commands */ esp_matter_command_create_off(cluster); esp_matter_command_create_on(cluster); esp_matter_command_create_toggle(cluster); @@ -785,15 +741,13 @@ esp_matter_cluster_t *esp_matter_cluster_create_level_control(esp_matter_endpoin esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterLevelControlPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->current_level)); - esp_matter_attribute_create(cluster, ZCL_ON_LEVEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->on_level)); - esp_matter_attribute_create(cluster, ZCL_OPTIONS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->options)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_current_level(cluster, config->current_level); + esp_matter_attribute_create_on_level(cluster, config->on_level); + esp_matter_attribute_create_options(cluster, config->options); + /* Commands */ esp_matter_command_create_move_to_level(cluster); esp_matter_command_create_move(cluster); esp_matter_command_create_step(cluster); @@ -825,23 +779,17 @@ esp_matter_cluster_t *esp_matter_cluster_create_color_control(esp_matter_endpoin esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterColorControlPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_FEATURE_MAP_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap32(config->feature_map)); - esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->current_hue)); - esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, - ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint8(config->current_saturation)); - esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->color_mode)); - esp_matter_attribute_create(cluster, ZCL_OPTIONS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->options)); - esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_ENHANCED_COLOR_MODE_ATTRIBUTE_ID, - ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_enum8(config->enhanced_color_mode)); - esp_matter_attribute_create(cluster, ZCL_COLOR_CONTROL_COLOR_CAPABILITIES_ATTRIBUTE_ID, - ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_bitmap16(config->color_capabilities)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_feature_map(cluster, config->feature_map); + esp_matter_attribute_create_current_hue(cluster, config->current_hue); + esp_matter_attribute_create_current_saturation(cluster, config->current_saturation); + esp_matter_attribute_create_color_mode(cluster, config->color_mode); + esp_matter_attribute_create_color_control_options(cluster, config->color_control_options); + esp_matter_attribute_create_enhanced_color_mode(cluster, config->enhanced_color_mode); + esp_matter_attribute_create_color_capabilities(cluster, config->color_capabilities); + /* Commands */ esp_matter_command_create_move_to_hue(cluster); esp_matter_command_create_move_hue(cluster); esp_matter_command_create_step_hue(cluster); @@ -874,31 +822,13 @@ esp_matter_cluster_t *esp_matter_cluster_create_fan_control(esp_matter_endpoint_ esp_matter_cluster_set_plugin_client_init_callback(cluster, NULL); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_FAN_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->fan_mode)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_FAN_MODE_SEQUENCE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->fan_mode_sequence)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_fan_mode(cluster, config->fan_mode); + esp_matter_attribute_create_fan_mode_sequence(cluster, config->fan_mode_sequence); /* Not implemented - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_PERCENT_SETTING_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->percent_setting)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_PERCENT_CURRENT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->percent_current)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_SPEED_MAX_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->speed_max)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_SPEED_SETTING_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->speed_max)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_SPEED_CURRENT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->speed_setting)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_ROCK_SUPPORT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->rock_support)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_ROCK_SETTING_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->rock_setting)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_WIND_SUPPORT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->wind_support)); - esp_matter_attribute_create(cluster, ZCL_FAN_CONTROL_WIND_SETTING_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap8(config->wind_setting)); + esp_matter_attribute_create_percent_setting(cluster, config->percent_setting); + esp_matter_attribute_create_percent_current(cluster, config->percent_current); */ return cluster; @@ -923,19 +853,15 @@ esp_matter_cluster_t *esp_matter_cluster_create_thermostat(esp_matter_endpoint_t esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterThermostatPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_LOCAL_TEMPERATURE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_int16(config->local_temperature)); - esp_matter_attribute_create(cluster, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_int16(config->occupied_cooling_setpoint)); - esp_matter_attribute_create(cluster, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_int16(config->occupied_heating_setpoint)); - esp_matter_attribute_create(cluster, ZCL_CONTROL_SEQUENCE_OF_OPERATION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->control_sequence_of_operation)); - esp_matter_attribute_create(cluster, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->system_mode)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_local_temperature(cluster, config->local_temperature); + esp_matter_attribute_create_occupied_cooling_setpoint(cluster, config->occupied_cooling_setpoint); + esp_matter_attribute_create_occupied_heating_setpoint(cluster, config->occupied_heating_setpoint); + esp_matter_attribute_create_control_sequence_of_operation(cluster, config->control_sequence_of_operation); + esp_matter_attribute_create_system_mode(cluster, config->system_mode); + /* Commands */ esp_matter_command_create_setpoint_raise_lower(cluster); return cluster; @@ -960,21 +886,16 @@ esp_matter_cluster_t *esp_matter_cluster_create_door_lock(esp_matter_endpoint_t esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterDoorLockPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_LOCK_STATE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->lock_state)); - esp_matter_attribute_create(cluster, ZCL_LOCK_TYPE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->lock_type)); - esp_matter_attribute_create(cluster, ZCL_ACTUATOR_ENABLED_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bool(config->actuator_enabled)); - esp_matter_attribute_create(cluster, ZCL_AUTO_RELOCK_TIME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint32(config->auto_relock_time)); - esp_matter_attribute_create(cluster, ZCL_OPERATING_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(config->operating_mode)); - esp_matter_attribute_create(cluster, ZCL_SUPPORTED_OPERATING_MODES_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bitmap16(config->supported_operating_modes)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_lock_state(cluster, config->lock_state); + esp_matter_attribute_create_lock_type(cluster, config->lock_type); + esp_matter_attribute_create_actuator_enabled(cluster, config->actuator_enabled); + esp_matter_attribute_create_auto_relock_time(cluster, config->auto_relock_time); + esp_matter_attribute_create_operating_mode(cluster, config->operating_mode); + esp_matter_attribute_create_supported_operating_modes(cluster, config->supported_operating_modes); + /* Commands */ esp_matter_command_create_lock_door(cluster); esp_matter_command_create_unlock_door(cluster); @@ -1000,8 +921,9 @@ esp_matter_cluster_t *esp_matter_cluster_create_time_synchronization(esp_matter_ esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterTimeSynchronizationPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + return cluster; } @@ -1021,12 +943,12 @@ esp_matter_cluster_t *esp_matter_cluster_create_bridged_device_basic(esp_matter_ esp_matter_cluster_bridged_device_basic_function_flags); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_NODE_LABEL_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_char_str(config->node_label, sizeof(config->node_label))); - esp_matter_attribute_create(cluster, ZCL_REACHABLE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_bool(config->reachable)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_bridged_device_basic_node_label(cluster, config->node_label, + sizeof(config->node_label)); + esp_matter_attribute_create_reachable(cluster, config->reachable); + return cluster; } @@ -1048,10 +970,12 @@ esp_matter_cluster_t *esp_matter_cluster_create_fixed_label(esp_matter_endpoint_ esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterFixedLabelPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_LABEL_LIST_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_array(config->label_list, sizeof(config->label_list), 0)); + /* Attributes managed internally */ + esp_matter_attribute_create_label_list(cluster, NULL, 0, 0); + + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + return cluster; } @@ -1073,14 +997,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_switch(esp_matter_endpoint_t *en esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterSwitchPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_NUMBER_OF_POSITIONS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->number_of_positions)); - esp_matter_attribute_create(cluster, ZCL_CURRENT_POSITION_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->current_position)); - esp_matter_attribute_create(cluster, ZCL_MULTI_PRESS_MAX_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint8(config->multi_press_max)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_number_of_positions(cluster, config->number_of_positions); + esp_matter_attribute_create_current_position(cluster, config->current_position); + esp_matter_attribute_create_multi_press_max(cluster, config->multi_press_max); return cluster; } @@ -1104,14 +1025,11 @@ esp_matter_cluster_t *esp_matter_cluster_create_temperature_measurement(esp_matt esp_matter_cluster_set_plugin_client_init_callback(cluster, MatterTemperatureMeasurementPluginClientInitCallback); } - esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(config->cluster_revision)); - esp_matter_attribute_create(cluster, ZCL_TEMP_MEASURED_VALUE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_int16(config->measured_value)); - esp_matter_attribute_create(cluster, ZCL_TEMP_MIN_MEASURED_VALUE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_int16(config->min_measured_value)); - esp_matter_attribute_create(cluster, ZCL_TEMP_MAX_MEASURED_VALUE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_int16(config->max_measured_value)); + /* Attributes not managed internally */ + esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); + esp_matter_attribute_create_temperature_measured_value(cluster, config->measured_value); + esp_matter_attribute_create_temperature_min_measured_value(cluster, config->min_measured_value); + esp_matter_attribute_create_temperature_max_measured_value(cluster, config->max_measured_value); return cluster; } diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 2adce4719..e2e1a2fc0 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -17,43 +17,15 @@ #include #include -#define CLUSTER_CONFIG_DESCRIPTOR_DEFAULT() \ - { \ - .cluster_revision = 1, \ - .device_type_list = {0}, \ - .server_list = {0}, \ - .client_list = {0}, \ - .parts_list = {0}, \ - } - -#define CLUSTER_CONFIG_ACCESS_CONTROL_DEFAULT() \ - { \ - .cluster_revision = 1, \ - .acl = {0}, \ - .extension = {0}, \ - } - #define CLUSTER_CONFIG_BASIC_DEFAULT() \ { \ .cluster_revision = 3, \ - .data_model_revision = 1, \ - .vendor_name = {0}, \ - .vendor_id = 0, \ - .product_name = {0}, \ - .product_id = 0, \ .node_label = {0}, \ - .location = {0}, \ - .hardware_version = 0, \ - .hardware_version_string = {0}, \ - .software_version = 0, \ - .software_version_string = {0}, \ - .serial_number = {0}, \ } #define CLUSTER_CONFIG_BINDING_DEFAULT() \ { \ .cluster_revision = 1, \ - .binding_list = {0}, \ } #define CLUSTER_CONFIG_OTA_PROVIDER_DEFAULT() \ @@ -64,7 +36,6 @@ #define CLUSTER_CONFIG_OTA_REQUESTOR_DEFAULT() \ { \ .cluster_revision = 1, \ - .default_ota_providers = {0}, \ .update_possible = 0, \ .update_state = 0, \ .update_state_progress = 0, \ @@ -74,58 +45,26 @@ { \ .cluster_revision = 1, \ .breadcrumb = 0, \ - .basic_commissioning_info = {0}, \ - .regulatory_config = 0, \ - .location_capability = 0, \ } #define CLUSTER_CONFIG_NETWORK_COMMISSIONING_DEFAULT() \ { \ .cluster_revision = 1, \ - .feature_map = 1, \ - .max_networks = 1, \ - .networks = {0}, \ - .scan_max_time_seconds = 0, \ - .connect_max_time_seconds = 0, \ - .interface_enabled = 0, \ - .last_networking_status = 0, \ - .last_network_id = {0}, \ - .last_connect_error_value = 0, \ } #define CLUSTER_CONFIG_GENERAL_DIAGNOSTICS_DEFAULT() \ { \ .cluster_revision = 1, \ - .network_interfaces = {0}, \ - .reboot_count = 0, \ } #define CLUSTER_CONFIG_ADMINISTRATOR_COMMISSIONING_DEFAULT() \ { \ .cluster_revision = 1, \ - .window_status = 0, \ - .admin_fabric_index = 0, \ - .admin_vendor_id = 0, \ } #define CLUSTER_CONFIG_OPERATIONAL_CREDENTIALS_DEFAULT() \ { \ .cluster_revision = 1, \ - .nocs = {0}, \ - .fabrics = {0}, \ - .supported_fabrics = 5, \ - .commissioned_fabrics = 0, \ - .trusted_root_certificates = {0}, \ - .current_fabric_index = 0, \ - } - -#define CLUSTER_CONFIG_GROUP_KEY_MANAGEMENT_DEFAULT() \ - { \ - .cluster_revision = 1, \ - .group_key_map = {0}, \ - .group_table = {0}, \ - .max_groups_per_fabric = 0, \ - .max_group_keys_per_fabric = 1, \ } #define CLUSTER_CONFIG_IDENTIFY_DEFAULT() \ @@ -138,7 +77,7 @@ #define CLUSTER_CONFIG_GROUPS_DEFAULT() \ { \ .cluster_revision = 3, \ - .name_support = 0, \ + .group_name_support = 0, \ } #define CLUSTER_CONFIG_SCENES_DEFAULT() \ @@ -148,7 +87,7 @@ .current_scene = 0, \ .current_group = 0, \ .scene_valid = false, \ - .name_support = 0, \ + .scene_name_support = 0, \ } #define CLUSTER_CONFIG_ON_OFF_DEFAULT() \ @@ -172,7 +111,7 @@ .current_hue = 0, \ .current_saturation = 0, \ .color_mode = 1, \ - .options = 0, \ + .color_control_options = 0, \ .enhanced_color_mode = 1, \ .color_capabilities = 0, \ } @@ -201,7 +140,7 @@ .lock_type = 0, \ .actuator_enabled = 0, \ .auto_relock_time = 0, \ - .operating_mode = 0, \ + .operating_mode = 0, \ .supported_operating_modes = 0, \ } @@ -220,7 +159,6 @@ #define CLUSTER_CONFIG_FIXED_LABEL_DEFAULT() \ { \ .cluster_revision = 1, \ - .label_list = {0}, \ } #define CLUSTER_CONFIG_SWITCH_DEFAULT() \ @@ -239,39 +177,13 @@ .max_measured_value = -32768, \ } -typedef struct esp_matter_cluster_descriptor_config { - uint16_t cluster_revision; - uint8_t device_type_list[254]; - uint8_t server_list[254]; - uint8_t client_list[254]; - uint8_t parts_list[254]; -} esp_matter_cluster_descriptor_config_t; - -typedef struct esp_matter_cluster_access_control_config { - uint16_t cluster_revision; - uint8_t acl[254]; - uint8_t extension[254]; -} esp_matter_cluster_access_control_config_t; - typedef struct esp_matter_cluster_basic_config { uint16_t cluster_revision; - uint16_t data_model_revision; - char vendor_name[32]; - uint16_t vendor_id; - char product_name[32]; - uint16_t product_id; char node_label[32]; - char location[2]; - uint16_t hardware_version; - char hardware_version_string[64]; - uint32_t software_version; - char software_version_string[64]; - char serial_number[32]; } esp_matter_cluster_basic_config_t; typedef struct esp_matter_cluster_binding_config { uint16_t cluster_revision; - uint8_t binding_list[254]; } esp_matter_cluster_binding_config_t; typedef struct esp_matter_cluster_ota_provider_config { @@ -280,7 +192,6 @@ typedef struct esp_matter_cluster_ota_provider_config { typedef struct esp_matter_cluster_ota_requestor_config { uint16_t cluster_revision; - uint8_t default_ota_providers[17]; bool update_possible; uint8_t update_state; uint8_t update_state_progress; @@ -289,55 +200,24 @@ typedef struct esp_matter_cluster_ota_requestor_config { typedef struct esp_matter_cluster_general_commissioning_config { uint16_t cluster_revision; uint64_t breadcrumb; - uint8_t basic_commissioning_info[254]; - uint8_t regulatory_config; - uint8_t location_capability; } esp_matter_cluster_general_commissioning_config_t; typedef struct esp_matter_cluster_network_commissioning_config { uint16_t cluster_revision; - uint32_t feature_map; - uint8_t max_networks; - uint8_t networks[12]; - uint8_t scan_max_time_seconds; - uint8_t connect_max_time_seconds; - bool interface_enabled; - uint8_t last_networking_status; - uint8_t last_network_id[32]; - uint32_t last_connect_error_value; } esp_matter_cluster_network_commissioning_config_t; typedef struct esp_matter_cluster_general_diagnostics_config { uint16_t cluster_revision; - uint8_t network_interfaces[254]; - uint16_t reboot_count; } esp_matter_cluster_general_diagnostics_config_t; typedef struct esp_matter_cluster_administrator_commissioning_config { uint16_t cluster_revision; - uint8_t window_status; - uint16_t admin_fabric_index; - uint16_t admin_vendor_id; } esp_matter_cluster_administrator_commissioning_config_t; typedef struct esp_matter_cluster_operational_credentials_config { uint16_t cluster_revision; - uint8_t nocs[254]; - uint8_t fabrics[320]; - uint8_t supported_fabrics; - uint8_t commissioned_fabrics; - uint8_t trusted_root_certificates[400]; - uint8_t current_fabric_index; } esp_matter_cluster_operational_credentials_config_t; -typedef struct esp_matter_cluster_group_key_management_config { - uint16_t cluster_revision; - uint8_t group_key_map[254]; - uint8_t group_table[254]; - uint16_t max_groups_per_fabric; - uint16_t max_group_keys_per_fabric; -} esp_matter_cluster_group_key_management_config_t; - typedef struct esp_matter_cluster_identify_config { uint16_t cluster_revision; uint16_t identify_time; @@ -346,7 +226,7 @@ typedef struct esp_matter_cluster_identify_config { typedef struct esp_matter_cluster_groups_config { uint16_t cluster_revision; - uint8_t name_support; + uint8_t group_name_support; } esp_matter_cluster_groups_config_t; typedef struct esp_matter_cluster_scenes_config { @@ -355,7 +235,7 @@ typedef struct esp_matter_cluster_scenes_config { uint8_t current_scene; uint16_t current_group; bool scene_valid; - uint8_t name_support; + uint8_t scene_name_support; } esp_matter_cluster_scenes_config_t; typedef struct esp_matter_cluster_on_off_config { @@ -376,7 +256,7 @@ typedef struct esp_matter_cluster_color_control_config { uint8_t current_hue; uint8_t current_saturation; uint8_t color_mode; - uint8_t options; + uint8_t color_control_options; uint8_t enhanced_color_mode; uint16_t color_capabilities; } esp_matter_cluster_color_control_config_t; @@ -388,13 +268,6 @@ typedef struct esp_matter_cluster_fan_control_config { /* Not implemented uint8_t percent_setting; uint8_t percent_current; - uint8_t speed_max; - uint8_t speed_setting; - uint8_t speed_current; - uint8_t rock_support; - uint8_t rock_setting; - uint8_t wind_support; - uint8_t wind_setting; */ } esp_matter_cluster_fan_control_config_t; @@ -429,7 +302,6 @@ typedef struct esp_matter_cluster_bridged_device_basic_config { typedef struct esp_matter_cluster_fixed_label_config { uint16_t cluster_revision; - uint8_t label_list[254]; } esp_matter_cluster_fixed_label_config_t; typedef struct esp_matter_cluster_switch_config { @@ -448,12 +320,8 @@ typedef struct esp_matter_cluster_temperature_measurement_config { void esp_matter_cluster_plugin_init_callback_common(); -esp_matter_cluster_t *esp_matter_cluster_create_descriptor(esp_matter_endpoint_t *endpoint, - esp_matter_cluster_descriptor_config_t *config, - uint8_t flags); -esp_matter_cluster_t *esp_matter_cluster_create_access_control(esp_matter_endpoint_t *endpoint, - esp_matter_cluster_access_control_config_t *config, - uint8_t flags); +esp_matter_cluster_t *esp_matter_cluster_create_descriptor(esp_matter_endpoint_t *endpoint, uint8_t flags); +esp_matter_cluster_t *esp_matter_cluster_create_access_control(esp_matter_endpoint_t *endpoint, uint8_t flags); esp_matter_cluster_t *esp_matter_cluster_create_basic(esp_matter_endpoint_t *endpoint, esp_matter_cluster_basic_config_t *config, uint8_t flags); esp_matter_cluster_t *esp_matter_cluster_create_binding(esp_matter_endpoint_t *endpoint, @@ -479,9 +347,7 @@ esp_matter_cluster_t *esp_matter_cluster_create_administrator_commissioning(esp_ esp_matter_cluster_t *esp_matter_cluster_create_operational_credentials(esp_matter_endpoint_t *endpoint, esp_matter_cluster_operational_credentials_config_t *config, uint8_t flags); -esp_matter_cluster_t *esp_matter_cluster_create_group_key_management(esp_matter_endpoint_t *endpoint, - esp_matter_cluster_group_key_management_config_t *config, - uint8_t flags); +esp_matter_cluster_t *esp_matter_cluster_create_group_key_management(esp_matter_endpoint_t *endpoint, uint8_t flags); esp_matter_cluster_t *esp_matter_cluster_create_identify(esp_matter_endpoint_t *endpoint, esp_matter_cluster_identify_config_t *config, uint8_t flags); diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index a8d05f712..bd03e97ec 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -820,7 +820,7 @@ esp_err_t esp_matter_attribute_set_val(esp_matter_attribute_t *attribute, esp_ma memcpy(new_buf, val->val.a.b, val->val.a.s); val->val.a.b = new_buf; } else { - ESP_LOGI(TAG, "Set val called with string with size 0"); + ESP_LOGD(TAG, "Set val called with string with size 0"); val->val.a.b = NULL; } } diff --git a/components/esp_matter/esp_matter_core.h b/components/esp_matter/esp_matter_core.h index c658af883..74b7d2662 100644 --- a/components/esp_matter/esp_matter_core.h +++ b/components/esp_matter/esp_matter_core.h @@ -15,7 +15,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 0c5a1ff0e..304125dfc 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -29,8 +29,8 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_root_node(esp_matter_node_t *n } esp_matter_endpoint_set_device_type_id(endpoint, ESP_MATTER_ROOT_NODE_DEVICE_TYPE_ID); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_access_control(endpoint, &(config->access_control), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_access_control(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_basic(endpoint, &(config->basic), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_ota_provider(endpoint, &(config->ota_provider), ESP_MATTER_CLUSTER_FLAG_CLIENT); esp_matter_cluster_create_ota_requestor(endpoint, &(config->ota_requestor), ESP_MATTER_CLUSTER_FLAG_SERVER); @@ -44,8 +44,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_root_node(esp_matter_node_t *n ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_operational_credentials(endpoint, &(config->operational_credentials), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_group_key_management(endpoint, &(config->group_key_management), - ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_group_key_management(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); return endpoint; } @@ -66,7 +65,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_on_off_light(esp_matter_node_t esp_matter_cluster_create_scenes(endpoint, &(config->scenes), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_on_off(endpoint, &(config->on_off), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_basic(endpoint, &(config->basic), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); return endpoint; } @@ -88,7 +87,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_dimmable_light(esp_matter_node esp_matter_cluster_create_on_off(endpoint, &(config->on_off), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_level_control(endpoint, &(config->level_control), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_basic(endpoint, &(config->basic), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); return endpoint; } @@ -110,7 +109,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_color_dimmable_light(esp_matte esp_matter_cluster_create_on_off(endpoint, &(config->on_off), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_level_control(endpoint, &(config->level_control), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_basic(endpoint, &(config->basic), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_color_control(endpoint, &(config->color_control), ESP_MATTER_CLUSTER_FLAG_SERVER); return endpoint; @@ -132,7 +131,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_on_off_switch(esp_matter_node_ esp_matter_cluster_create_scenes(endpoint, &(config->scenes), ESP_MATTER_CLUSTER_FLAG_CLIENT); esp_matter_cluster_create_on_off(endpoint, &(config->on_off), ESP_MATTER_CLUSTER_FLAG_CLIENT); esp_matter_cluster_create_basic(endpoint, &(config->basic), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_binding(endpoint, &(config->binding), ESP_MATTER_CLUSTER_FLAG_SERVER); return endpoint; @@ -151,7 +150,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_fan(esp_matter_node_t *node, esp_matter_cluster_create_identify(endpoint, &(config->identify), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_groups(endpoint, &(config->groups), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_fan_control(endpoint, &(config->fan_control), ESP_MATTER_CLUSTER_FLAG_SERVER); return endpoint; @@ -172,7 +171,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_thermostat(esp_matter_node_t * esp_matter_cluster_create_groups(endpoint, &(config->groups), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_scenes(endpoint, &(config->scenes), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_basic(endpoint, &(config->basic), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_thermostat(endpoint, &(config->thermostat), ESP_MATTER_CLUSTER_FLAG_SERVER); return endpoint; @@ -191,7 +190,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_bridged_node(esp_matter_node_t esp_matter_endpoint_set_device_type_id(endpoint, ESP_MATTER_BRIDGED_NODE_DEVICE_TYPE_ID); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_bridged_device_basic(endpoint, &(config->bridged_device_basic), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_fixed_label(endpoint, &(config->fixed_label), ESP_MATTER_CLUSTER_FLAG_SERVER); @@ -212,7 +211,7 @@ esp_matter_endpoint_t *esp_matter_endpoint_create_door_lock(esp_matter_node_t *n esp_matter_endpoint_set_device_type_id(endpoint, ESP_MATTER_DOOR_LOCK_DEVICE_TYPE_ID); esp_matter_cluster_create_identify(endpoint, &(config->identify), ESP_MATTER_CLUSTER_FLAG_SERVER); - esp_matter_cluster_create_descriptor(endpoint, &(config->descriptor), ESP_MATTER_CLUSTER_FLAG_SERVER); + esp_matter_cluster_create_descriptor(endpoint, ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_door_lock(endpoint, &(config->door_lock), ESP_MATTER_CLUSTER_FLAG_SERVER); esp_matter_cluster_create_time_synchronization(endpoint, &(config->time_synchronization), ESP_MATTER_CLUSTER_FLAG_SERVER); diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index 6fa2c45f6..7820d2c7b 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -30,8 +30,6 @@ #define ENDPOINT_CONFIG_ROOT_NODE_DEFAULT() \ { \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ - .access_control = CLUSTER_CONFIG_ACCESS_CONTROL_DEFAULT(), \ .basic = CLUSTER_CONFIG_BASIC_DEFAULT(), \ .ota_provider = CLUSTER_CONFIG_OTA_PROVIDER_DEFAULT(), \ .ota_requestor = CLUSTER_CONFIG_OTA_REQUESTOR_DEFAULT(), \ @@ -40,7 +38,6 @@ .general_diagnostics = CLUSTER_CONFIG_GENERAL_DIAGNOSTICS_DEFAULT(), \ .administrator_commissioning = CLUSTER_CONFIG_ADMINISTRATOR_COMMISSIONING_DEFAULT(), \ .operational_credentials = CLUSTER_CONFIG_OPERATIONAL_CREDENTIALS_DEFAULT(), \ - .group_key_management = CLUSTER_CONFIG_GROUP_KEY_MANAGEMENT_DEFAULT(), \ } #define ENDPOINT_CONFIG_ON_OFF_LIGHT_DEFAULT() \ @@ -50,7 +47,6 @@ .scenes = CLUSTER_CONFIG_SCENES_DEFAULT(), \ .on_off = CLUSTER_CONFIG_ON_OFF_DEFAULT(), \ .basic = CLUSTER_CONFIG_BASIC_DEFAULT(), \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ } #define ENDPOINT_CONFIG_DIMMABLE_LIGHT_DEFAULT() \ @@ -61,7 +57,6 @@ .on_off = CLUSTER_CONFIG_ON_OFF_DEFAULT(), \ .level_control = CLUSTER_CONFIG_LEVEL_CONTROL_DEFAULT(), \ .basic = CLUSTER_CONFIG_BASIC_DEFAULT(), \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ } #define ENDPOINT_CONFIG_COLOR_DIMMABLE_LIGHT_DEFAULT() \ @@ -73,7 +68,6 @@ .level_control = CLUSTER_CONFIG_LEVEL_CONTROL_DEFAULT(), \ .basic = CLUSTER_CONFIG_BASIC_DEFAULT(), \ .color_control = CLUSTER_CONFIG_COLOR_CONTROL_DEFAULT(), \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ } #define ENDPOINT_CONFIG_ON_OFF_SWITCH_DEFAULT() \ @@ -84,14 +78,12 @@ .on_off = CLUSTER_CONFIG_ON_OFF_DEFAULT(), \ .basic = CLUSTER_CONFIG_BASIC_DEFAULT(), \ .binding = CLUSTER_CONFIG_BINDING_DEFAULT(), \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ } #define ENDPOINT_CONFIG_FAN_DEFAULT() \ { \ .identify = CLUSTER_CONFIG_IDENTIFY_DEFAULT(), \ .groups = CLUSTER_CONFIG_GROUPS_DEFAULT(), \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ .fan_control = CLUSTER_CONFIG_FAN_CONTROL_DEFAULT(), \ } @@ -102,20 +94,17 @@ .scenes = CLUSTER_CONFIG_SCENES_DEFAULT(), \ .basic = CLUSTER_CONFIG_BASIC_DEFAULT(), \ .thermostat = CLUSTER_CONFIG_THERMOSTAT_DEFAULT(), \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ } #define ENDPOINT_CONFIG_DOOR_LOCK_DEFAULT() \ { \ .identify = CLUSTER_CONFIG_IDENTIFY_DEFAULT(), \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ .door_lock = CLUSTER_CONFIG_DOOR_LOCK_DEFAULT(), \ .time_synchronization = CLUSTER_CONFIG_TIME_SYNCHRONIZATION_DEFAULT(), \ } #define ENDPOINT_CONFIG_BRIDGED_NODE_DEFAULT() \ { \ - .descriptor = CLUSTER_CONFIG_DESCRIPTOR_DEFAULT(), \ .bridged_device_basic = CLUSTER_CONFIG_BRIDGED_DEVICE_BASIC_DEFAULT(), \ .fixed_label = CLUSTER_CONFIG_FIXED_LABEL_DEFAULT(), \ } @@ -133,8 +122,6 @@ } typedef struct esp_matter_endpoint_root_node_config { - esp_matter_cluster_descriptor_config_t descriptor; - esp_matter_cluster_access_control_config_t access_control; esp_matter_cluster_basic_config_t basic; esp_matter_cluster_ota_provider_config_t ota_provider; esp_matter_cluster_ota_requestor_config_t ota_requestor; @@ -143,7 +130,6 @@ typedef struct esp_matter_endpoint_root_node_config { esp_matter_cluster_general_diagnostics_config_t general_diagnostics; esp_matter_cluster_administrator_commissioning_config_t administrator_commissioning; esp_matter_cluster_operational_credentials_config_t operational_credentials; - esp_matter_cluster_group_key_management_config_t group_key_management; } esp_matter_endpoint_root_node_config_t; typedef struct esp_matter_endpoint_on_off_light_config { @@ -152,7 +138,6 @@ typedef struct esp_matter_endpoint_on_off_light_config { esp_matter_cluster_scenes_config_t scenes; esp_matter_cluster_on_off_config_t on_off; esp_matter_cluster_basic_config_t basic; - esp_matter_cluster_descriptor_config_t descriptor; } esp_matter_endpoint_on_off_light_config_t; typedef struct esp_matter_endpoint_dimmable_light_config { @@ -162,7 +147,6 @@ typedef struct esp_matter_endpoint_dimmable_light_config { esp_matter_cluster_on_off_config_t on_off; esp_matter_cluster_level_control_config_t level_control; esp_matter_cluster_basic_config_t basic; - esp_matter_cluster_descriptor_config_t descriptor; } esp_matter_endpoint_dimmable_light_config_t; typedef struct esp_matter_endpoint_color_dimmable_light_config { @@ -173,7 +157,6 @@ typedef struct esp_matter_endpoint_color_dimmable_light_config { esp_matter_cluster_level_control_config_t level_control; esp_matter_cluster_basic_config_t basic; esp_matter_cluster_color_control_config_t color_control; - esp_matter_cluster_descriptor_config_t descriptor; } esp_matter_endpoint_color_dimmable_light_config_t; typedef struct esp_matter_endpoint_on_off_switch_config { @@ -183,13 +166,11 @@ typedef struct esp_matter_endpoint_on_off_switch_config { esp_matter_cluster_on_off_config_t on_off; esp_matter_cluster_basic_config_t basic; esp_matter_cluster_binding_config_t binding; - esp_matter_cluster_descriptor_config_t descriptor; } esp_matter_endpoint_on_off_switch_config_t; typedef struct esp_matter_endpoint_fan_config { esp_matter_cluster_identify_config_t identify; esp_matter_cluster_groups_config_t groups; - esp_matter_cluster_descriptor_config_t descriptor; esp_matter_cluster_fan_control_config_t fan_control; } esp_matter_endpoint_fan_config_t; @@ -199,18 +180,15 @@ typedef struct esp_matter_endpoint_thermostat_config { esp_matter_cluster_scenes_config_t scenes; esp_matter_cluster_basic_config_t basic; esp_matter_cluster_thermostat_config_t thermostat; - esp_matter_cluster_descriptor_config_t descriptor; } esp_matter_endpoint_thermostat_config_t; typedef struct esp_matter_endpoint_bridged_node_config { - esp_matter_cluster_descriptor_config_t descriptor; esp_matter_cluster_bridged_device_basic_config_t bridged_device_basic; esp_matter_cluster_fixed_label_config_t fixed_label; } esp_matter_endpoint_bridged_node_config_t; typedef struct esp_matter_endpoint_door_lock_config { esp_matter_cluster_identify_config_t identify; - esp_matter_cluster_descriptor_config_t descriptor; esp_matter_cluster_door_lock_config_t door_lock; esp_matter_cluster_time_synchronization_config_t time_synchronization; } esp_matter_endpoint_door_lock_config_t; diff --git a/examples/bridge_zigbee/main/zigbee_bridge.h b/examples/bridge_zigbee/main/zigbee_bridge.h index e363118ba..b44fe7166 100644 --- a/examples/bridge_zigbee/main/zigbee_bridge.h +++ b/examples/bridge_zigbee/main/zigbee_bridge.h @@ -13,7 +13,7 @@ extern "C" { #include -#include +#include #include #include From 6a28250523ba7fbca29ee1b2d8fbeb34fe09fad6 Mon Sep 17 00:00:00 2001 From: Chirag Atal Date: Thu, 17 Mar 2022 20:04:03 +0530 Subject: [PATCH 2/2] esp_matter_core: Fix the default attribute value The default value of the attribute being set when creating the submodule data model was incorrect. Also adding support for attribute bounds. --- .../esp_matter/esp_matter_attribute.cpp | 73 +++++-- components/esp_matter/esp_matter_attribute.h | 15 +- .../esp_matter/esp_matter_attribute_utils.cpp | 122 +---------- .../esp_matter/esp_matter_attribute_utils.h | 9 + components/esp_matter/esp_matter_cluster.cpp | 10 +- components/esp_matter/esp_matter_core.cpp | 194 ++++++++++++++++-- components/esp_matter/esp_matter_core.h | 3 + 7 files changed, 271 insertions(+), 155 deletions(-) diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index eda99c528..bb2df97de 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -14,6 +14,8 @@ #include +static const char *TAG = "esp_matter_attribute"; + esp_matter_attribute_t *esp_matter_attribute_create_cluster_revision(esp_matter_cluster_t *cluster, uint16_t value) { return esp_matter_attribute_create(cluster, ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID, @@ -348,10 +350,18 @@ esp_matter_attribute_t *esp_matter_attribute_create_max_group_keys_per_fabric(es ESP_MATTER_ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); } -esp_matter_attribute_t *esp_matter_attribute_create_identify_time(esp_matter_cluster_t *cluster, uint16_t value) +esp_matter_attribute_t *esp_matter_attribute_create_identify_time(esp_matter_cluster_t *cluster, uint16_t value, + uint16_t min, uint16_t max) { - return esp_matter_attribute_create(cluster, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, - esp_matter_uint16(value)); + esp_matter_attribute_t *attribute = esp_matter_attribute_create(cluster, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter_attribute_add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } esp_matter_attribute_t *esp_matter_attribute_create_identify_type(esp_matter_cluster_t *cluster, uint8_t value) @@ -414,10 +424,18 @@ esp_matter_attribute_t *esp_matter_attribute_create_on_level(esp_matter_cluster_ esp_matter_uint8(value)); } -esp_matter_attribute_t *esp_matter_attribute_create_options(esp_matter_cluster_t *cluster, uint8_t value) +esp_matter_attribute_t *esp_matter_attribute_create_options(esp_matter_cluster_t *cluster, uint8_t value, uint8_t min, + uint8_t max) { - return esp_matter_attribute_create(cluster, ZCL_OPTIONS_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, - esp_matter_bitmap8(value)); + esp_matter_attribute_t *attribute = esp_matter_attribute_create(cluster, ZCL_OPTIONS_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_bitmap8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter_attribute_add_bounds(attribute, esp_matter_bitmap8(min), esp_matter_bitmap8(max)); + return attribute; } esp_matter_attribute_t *esp_matter_attribute_create_current_hue(esp_matter_cluster_t *cluster, uint8_t value) @@ -489,16 +507,33 @@ esp_matter_attribute_t *esp_matter_attribute_create_occupied_heating_setpoint(es } esp_matter_attribute_t *esp_matter_attribute_create_control_sequence_of_operation(esp_matter_cluster_t *cluster, - uint8_t value) + uint8_t value, uint8_t min, + uint8_t max) { - return esp_matter_attribute_create(cluster, ZCL_CONTROL_SEQUENCE_OF_OPERATION_ATTRIBUTE_ID, - ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, esp_matter_enum8(value)); + esp_matter_attribute_t *attribute = esp_matter_attribute_create(cluster, + ZCL_CONTROL_SEQUENCE_OF_OPERATION_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_enum8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter_attribute_add_bounds(attribute, esp_matter_enum8(min), esp_matter_enum8(max)); + return attribute; } -esp_matter_attribute_t *esp_matter_attribute_create_system_mode(esp_matter_cluster_t *cluster, uint8_t value) +esp_matter_attribute_t *esp_matter_attribute_create_system_mode(esp_matter_cluster_t *cluster, uint8_t value, + uint8_t min, uint8_t max) { - return esp_matter_attribute_create(cluster, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, - esp_matter_enum8(value)); + esp_matter_attribute_t *attribute = esp_matter_attribute_create(cluster, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_WRITABLE, + esp_matter_enum8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter_attribute_add_bounds(attribute, esp_matter_enum8(min), esp_matter_enum8(max)); + return attribute; } esp_matter_attribute_t *esp_matter_attribute_create_lock_state(esp_matter_cluster_t *cluster, uint8_t value) @@ -525,10 +560,18 @@ esp_matter_attribute_t *esp_matter_attribute_create_auto_relock_time(esp_matter_ esp_matter_bitmap32(value)); } -esp_matter_attribute_t *esp_matter_attribute_create_operating_mode(esp_matter_cluster_t *cluster, uint8_t value) +esp_matter_attribute_t *esp_matter_attribute_create_operating_mode(esp_matter_cluster_t *cluster, uint8_t value, + uint8_t min, uint8_t max) { - return esp_matter_attribute_create(cluster, ZCL_OPERATING_MODE_ATTRIBUTE_ID, ESP_MATTER_ATTRIBUTE_FLAG_NONE, - esp_matter_enum8(value)); + esp_matter_attribute_t *attribute = esp_matter_attribute_create(cluster, ZCL_OPERATING_MODE_ATTRIBUTE_ID, + ESP_MATTER_ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter_attribute_add_bounds(attribute, esp_matter_enum8(min), esp_matter_enum8(max)); + return attribute; } esp_matter_attribute_t *esp_matter_attribute_create_supported_operating_modes(esp_matter_cluster_t *cluster, diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 1038e4c41..9b9137027 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -123,7 +123,8 @@ esp_matter_attribute_t *esp_matter_attribute_create_max_group_keys_per_fabric(es uint16_t value); /** cluster: identify */ -esp_matter_attribute_t *esp_matter_attribute_create_identify_time(esp_matter_cluster_t *cluster, uint16_t value); +esp_matter_attribute_t *esp_matter_attribute_create_identify_time(esp_matter_cluster_t *cluster, uint16_t value, + uint16_t min, uint16_t max); esp_matter_attribute_t *esp_matter_attribute_create_identify_type(esp_matter_cluster_t *cluster, uint8_t value); /** cluster: groups */ @@ -142,7 +143,8 @@ esp_matter_attribute_t *esp_matter_attribute_create_on_off(esp_matter_cluster_t /** cluster: level control */ esp_matter_attribute_t *esp_matter_attribute_create_current_level(esp_matter_cluster_t *cluster, uint8_t value); esp_matter_attribute_t *esp_matter_attribute_create_on_level(esp_matter_cluster_t *cluster, uint8_t value); -esp_matter_attribute_t *esp_matter_attribute_create_options(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_options(esp_matter_cluster_t *cluster, uint8_t value, uint8_t min, + uint8_t max); /** cluster: color control */ esp_matter_attribute_t *esp_matter_attribute_create_current_hue(esp_matter_cluster_t *cluster, uint8_t value); @@ -163,15 +165,18 @@ esp_matter_attribute_t *esp_matter_attribute_create_occupied_cooling_setpoint(es esp_matter_attribute_t *esp_matter_attribute_create_occupied_heating_setpoint(esp_matter_cluster_t *cluster, uint16_t value); esp_matter_attribute_t *esp_matter_attribute_create_control_sequence_of_operation(esp_matter_cluster_t *cluster, - uint8_t value); -esp_matter_attribute_t *esp_matter_attribute_create_system_mode(esp_matter_cluster_t *cluster, uint8_t value); + uint8_t value, uint8_t min, + uint8_t max); +esp_matter_attribute_t *esp_matter_attribute_create_system_mode(esp_matter_cluster_t *cluster, uint8_t value, + uint8_t min, uint8_t max); /** cluster: door lock */ esp_matter_attribute_t *esp_matter_attribute_create_lock_state(esp_matter_cluster_t *cluster, uint8_t value); esp_matter_attribute_t *esp_matter_attribute_create_lock_type(esp_matter_cluster_t *cluster, uint8_t value); esp_matter_attribute_t *esp_matter_attribute_create_actuator_enabled(esp_matter_cluster_t *cluster, bool value); esp_matter_attribute_t *esp_matter_attribute_create_auto_relock_time(esp_matter_cluster_t *cluster, uint32_t value); -esp_matter_attribute_t *esp_matter_attribute_create_operating_mode(esp_matter_cluster_t *cluster, uint8_t value); +esp_matter_attribute_t *esp_matter_attribute_create_operating_mode(esp_matter_cluster_t *cluster, uint8_t value, + uint8_t min, uint8_t max); esp_matter_attribute_t *esp_matter_attribute_create_supported_operating_modes(esp_matter_cluster_t *cluster, uint16_t value); diff --git a/components/esp_matter/esp_matter_attribute_utils.cpp b/components/esp_matter/esp_matter_attribute_utils.cpp index 72e18ad61..8bfb45356 100644 --- a/components/esp_matter/esp_matter_attribute_utils.cpp +++ b/components/esp_matter/esp_matter_attribute_utils.cpp @@ -76,6 +76,9 @@ static esp_err_t esp_matter_attribute_console_handler(int argc, char **argv) } else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { char *value = argv[4]; val = esp_matter_char_str(value, strlen(value)); + } else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) { + uint8_t value = atoi(argv[4]); + val = esp_matter_bitmap8(value); } else { ESP_LOGE(TAG, "Type not handled: %d", type); return ESP_ERR_INVALID_ARG; @@ -135,6 +138,10 @@ static esp_err_t esp_matter_attribute_console_handler(int argc, char **argv) int data_count = 0; memcpy(&data_count, &value[0], data_size_len); val = esp_matter_char_str((char *)(value + data_size_len), data_count); + } else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) { + uint8_t value = 0; + esp_matter_attribute_get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); + val = esp_matter_bitmap8(value); } else { ESP_LOGE(TAG, "Type not handled: %d", type); return ESP_ERR_INVALID_ARG; @@ -440,117 +447,8 @@ static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type return ESP_MATTER_VAL_TYPE_INVALID; } -esp_err_t esp_matter_attribute_get_type_and_val_default(esp_matter_attr_val_t *val, - EmberAfAttributeType *attribute_type, uint16_t *attribute_size, - EmberAfDefaultOrMinMaxAttributeValue *default_value) -{ - switch (val->type) { - case ESP_MATTER_VAL_TYPE_BOOLEAN: - *attribute_type = ZCL_BOOLEAN_ATTRIBUTE_TYPE; - *attribute_size = sizeof(bool); - *default_value = (uint16_t)val->val.b; - break; - - case ESP_MATTER_VAL_TYPE_INTEGER: - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *default_value = (uint16_t)val->val.i; - break; - - case ESP_MATTER_VAL_TYPE_FLOAT: - *attribute_type = ZCL_SINGLE_ATTRIBUTE_TYPE; - *attribute_size = sizeof(float); - *default_value = (uint8_t *)&val->val.f; - break; - - case ESP_MATTER_VAL_TYPE_ARRAY: - *attribute_type = ZCL_ARRAY_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.t; - *default_value = (uint8_t *)val->val.a.b; - break; - - case ESP_MATTER_VAL_TYPE_CHAR_STRING: - *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.t; - *default_value = (uint8_t *)val->val.a.b; - break; - - case ESP_MATTER_VAL_TYPE_OCTET_STRING: - *attribute_type = ZCL_OCTET_STRING_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.t; - *default_value = (uint8_t *)val->val.a.b; - break; - - case ESP_MATTER_VAL_TYPE_INT8: - *attribute_type = ZCL_INT8S_ATTRIBUTE_TYPE; - *attribute_size = sizeof(int8_t); - *default_value = (uint16_t)val->val.i8; - break; - - case ESP_MATTER_VAL_TYPE_UINT8: - *attribute_type = ZCL_INT8U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *default_value = (uint16_t)val->val.u8; - break; - - case ESP_MATTER_VAL_TYPE_INT16: - *attribute_type = ZCL_INT16S_ATTRIBUTE_TYPE; - *attribute_size = sizeof(int16_t); - *default_value = (int16_t)val->val.i16; - break; - - case ESP_MATTER_VAL_TYPE_UINT16: - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *default_value = (uint16_t)val->val.u16; - break; - - case ESP_MATTER_VAL_TYPE_UINT32: - *attribute_type = ZCL_INT32U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint32_t); - *default_value = (uint8_t *)&val->val.u32; - break; - - case ESP_MATTER_VAL_TYPE_UINT64: - *attribute_type = ZCL_INT64U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint64_t); - *default_value = (uint8_t *)&val->val.u64; - break; - - case ESP_MATTER_VAL_TYPE_ENUM8: - *attribute_type = ZCL_ENUM8_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *default_value = (uint16_t)val->val.u8; - break; - - case ESP_MATTER_VAL_TYPE_BITMAP8: - *attribute_type = ZCL_BITMAP8_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *default_value = (uint16_t)val->val.u8; - break; - - case ESP_MATTER_VAL_TYPE_BITMAP16: - *attribute_type = ZCL_BITMAP16_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *default_value = (uint16_t)val->val.u16; - break; - - case ESP_MATTER_VAL_TYPE_BITMAP32: - *attribute_type = ZCL_BITMAP32_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint32_t); - *default_value = (uint8_t *)&val->val.u32; - break; - - default: - ESP_LOGE(TAG, "esp_matter_attr_val_type_t not handled: %d", val->type); - break; - } - - return ESP_OK; -} - -static esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, - uint16_t *attribute_size, uint8_t *value) +esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, + uint16_t *attribute_size, uint8_t *value) { switch (val->type) { case ESP_MATTER_VAL_TYPE_BOOLEAN: @@ -980,7 +878,7 @@ esp_err_t esp_matter_attribute_update(int endpoint_id, int cluster_id, int attri if (emberAfContainsServer(endpoint_id, cluster_id)) { status = emberAfWriteServerAttribute(endpoint_id, cluster_id, attribute_id, value, attribute_type); if (status != EMBER_ZCL_STATUS_SUCCESS) { - ESP_LOGE(TAG, "Error updating attribute to matter"); + ESP_LOGE(TAG, "Error updating attribute to matter: 0x%X", status); free(value); if (lock_status == ESP_MATTER_LOCK_SUCCESS) { esp_matter_chip_stack_unlock(); diff --git a/components/esp_matter/esp_matter_attribute_utils.h b/components/esp_matter/esp_matter_attribute_utils.h index 4f88469d0..ac438d898 100644 --- a/components/esp_matter/esp_matter_attribute_utils.h +++ b/components/esp_matter/esp_matter_attribute_utils.h @@ -101,6 +101,15 @@ typedef struct { esp_matter_val_t val; } esp_matter_attr_val_t; +/* ESP Matter Attribute Bounds */ +typedef struct esp_matter_attr_bounds { + /* Minimum Value */ + esp_matter_attr_val_t min; + /* Maximum Value */ + esp_matter_attr_val_t max; + /** TODO: Step Value might be needed here later */ +} esp_matter_attr_bounds_t; + /*** Attribute val APIs ***/ /** Invalid */ esp_matter_attr_val_t esp_matter_invalid(void *val); diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 553f753ab..941c8a9db 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -600,7 +600,7 @@ esp_matter_cluster_t *esp_matter_cluster_create_identify(esp_matter_endpoint_t * /* Attributes not managed internally */ esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); - esp_matter_attribute_create_identify_time(cluster, config->identify_time); + esp_matter_attribute_create_identify_time(cluster, config->identify_time, 0x0, 0xFE); esp_matter_attribute_create_identify_type(cluster, config->identify_type); /* Commands */ @@ -745,7 +745,7 @@ esp_matter_cluster_t *esp_matter_cluster_create_level_control(esp_matter_endpoin esp_matter_attribute_create_cluster_revision(cluster, config->cluster_revision); esp_matter_attribute_create_current_level(cluster, config->current_level); esp_matter_attribute_create_on_level(cluster, config->on_level); - esp_matter_attribute_create_options(cluster, config->options); + esp_matter_attribute_create_options(cluster, config->options, 0x0, 0x3); /* Commands */ esp_matter_command_create_move_to_level(cluster); @@ -858,8 +858,8 @@ esp_matter_cluster_t *esp_matter_cluster_create_thermostat(esp_matter_endpoint_t esp_matter_attribute_create_local_temperature(cluster, config->local_temperature); esp_matter_attribute_create_occupied_cooling_setpoint(cluster, config->occupied_cooling_setpoint); esp_matter_attribute_create_occupied_heating_setpoint(cluster, config->occupied_heating_setpoint); - esp_matter_attribute_create_control_sequence_of_operation(cluster, config->control_sequence_of_operation); - esp_matter_attribute_create_system_mode(cluster, config->system_mode); + esp_matter_attribute_create_control_sequence_of_operation(cluster, config->control_sequence_of_operation, 0x0, 0x5); + esp_matter_attribute_create_system_mode(cluster, config->system_mode, 0x0, 0x7); /* Commands */ esp_matter_command_create_setpoint_raise_lower(cluster); @@ -892,7 +892,7 @@ esp_matter_cluster_t *esp_matter_cluster_create_door_lock(esp_matter_endpoint_t esp_matter_attribute_create_lock_type(cluster, config->lock_type); esp_matter_attribute_create_actuator_enabled(cluster, config->actuator_enabled); esp_matter_attribute_create_auto_relock_time(cluster, config->auto_relock_time); - esp_matter_attribute_create_operating_mode(cluster, config->operating_mode); + esp_matter_attribute_create_operating_mode(cluster, config->operating_mode, 0x0, 0x4); esp_matter_attribute_create_supported_operating_modes(cluster, config->supported_operating_modes); /* Commands */ diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index bd03e97ec..618355a91 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -58,6 +58,9 @@ typedef struct esp_matter_attribute { int attribute_id; uint8_t flags; esp_matter_attr_val_t val; + esp_matter_attr_bounds_t *bounds; + EmberAfDefaultOrMinMaxAttributeValue default_value; + uint16_t default_value_size; struct esp_matter_attribute *next; } _esp_matter_attribute_t; @@ -96,7 +99,7 @@ typedef struct esp_matter_node { static _esp_matter_node_t *node = NULL; -static int esp_matter_cluster_get_count(_esp_matter_cluster_t *current) +static int cluster_get_count(_esp_matter_cluster_t *current) { int count = 0; while (current) { @@ -106,7 +109,7 @@ static int esp_matter_cluster_get_count(_esp_matter_cluster_t *current) return count; } -static int esp_matter_attribute_get_count(_esp_matter_attribute_t *current) +static int attribute_get_count(_esp_matter_attribute_t *current) { int count = 0; while (current) { @@ -116,7 +119,7 @@ static int esp_matter_attribute_get_count(_esp_matter_attribute_t *current) return count; } -static int esp_matter_command_get_count(_esp_matter_command_t *current, int command_flag) +static int command_get_count(_esp_matter_command_t *current, int command_flag) { int count = 0; while (current) { @@ -128,7 +131,7 @@ static int esp_matter_command_get_count(_esp_matter_command_t *current, int comm return count; } -static int esp_matter_endpoint_get_next_index() +static int endpoint_get_next_index() { int endpoint_id = 0; for (int index = 0; index < MAX_ENDPOINT_COUNT; index++) { @@ -140,6 +143,108 @@ static int esp_matter_endpoint_get_next_index() return 0xFFFF; } +extern esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, + uint16_t *attribute_size, uint8_t *value); + +static esp_err_t attribute_free_default_value(esp_matter_attribute_t *attribute) +{ + if (!attribute) { + ESP_LOGE(TAG, "Attribute cannot be NULL"); + return ESP_FAIL; + } + _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)attribute; + + /* Free value if data is more than 2 bytes or if it is min max attribute */ + if (current_attribute->flags & ESP_MATTER_ATTRIBUTE_FLAG_MIN_MAX) { + if (current_attribute->default_value_size > 2) { + if (current_attribute->default_value.ptrToMinMaxValue->defaultValue.ptrToDefaultValue) { + free((void *)current_attribute->default_value.ptrToMinMaxValue->defaultValue.ptrToDefaultValue); + } + if (current_attribute->default_value.ptrToMinMaxValue->minValue.ptrToDefaultValue) { + free((void *)current_attribute->default_value.ptrToMinMaxValue->minValue.ptrToDefaultValue); + } + if (current_attribute->default_value.ptrToMinMaxValue->maxValue.ptrToDefaultValue) { + free((void *)current_attribute->default_value.ptrToMinMaxValue->maxValue.ptrToDefaultValue); + } + } + free((void *)current_attribute->default_value.ptrToMinMaxValue); + } else if (current_attribute->default_value_size > 2) { + if (current_attribute->default_value.ptrToDefaultValue) { + free((void *)current_attribute->default_value.ptrToDefaultValue); + } + } + return ESP_OK; +} + +static EmberAfDefaultAttributeValue get_default_value_from_data(esp_matter_attr_val_t *val, + EmberAfAttributeType attribute_type, + uint16_t attribute_size) +{ + EmberAfDefaultAttributeValue default_value = (uint16_t)0; + uint8_t *value = (uint8_t *)calloc(1, attribute_size); + if (!value) { + ESP_LOGE(TAG, "Could not allocate value buffer for default value"); + return default_value; + } + get_data_from_attr_val(val, &attribute_type, &attribute_size, value); + + if (attribute_size > 2) { + /* Directly set the pointer */ + default_value = value; + } else { + /* This data is 2 bytes or less. This should be represented as uint16. Copy the bytes appropriately + for 0 or 1 or 2 bytes to be converted to uint16. Then free the allocated buffer. */ + uint16_t int_value = 0; + if (attribute_size == 2) { + memcpy(&int_value, value, attribute_size); + } else if (attribute_size == 1) { + int_value = (uint16_t)*value; + } + default_value = int_value; + free(value); + } + return default_value; +} + +static esp_err_t attribute_set_default_value_from_current_val(esp_matter_attribute_t *attribute) +{ + if (!attribute) { + ESP_LOGE(TAG, "Attribute cannot be NULL"); + return ESP_FAIL; + } + _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)attribute; + esp_matter_attr_val_t *val = ¤t_attribute->val; + + /* Get size */ + EmberAfAttributeType attribute_type = 0; + uint16_t attribute_size = 0; + get_data_from_attr_val(val, &attribute_type, &attribute_size, NULL); + + /* Get and set value */ + if (current_attribute->flags & ESP_MATTER_ATTRIBUTE_FLAG_MIN_MAX) { + EmberAfAttributeMinMaxValue *temp_value = (EmberAfAttributeMinMaxValue *)calloc(1, + sizeof(EmberAfAttributeMinMaxValue)); + if (!temp_value) { + ESP_LOGE(TAG, "Could not allocate ptrToMinMaxValue for default value"); + return ESP_FAIL; + } + temp_value->defaultValue = get_default_value_from_data(val, attribute_type, attribute_size); + temp_value->minValue = get_default_value_from_data(¤t_attribute->bounds->min, + attribute_type, attribute_size); + temp_value->maxValue = get_default_value_from_data(¤t_attribute->bounds->max, + attribute_type, attribute_size); + current_attribute->default_value.ptrToMinMaxValue = temp_value; + } else if (attribute_size > 2) { + EmberAfDefaultAttributeValue temp_value = get_default_value_from_data(val, attribute_type, attribute_size); + current_attribute->default_value.ptrToDefaultValue = temp_value.ptrToDefaultValue; + } else { + EmberAfDefaultAttributeValue temp_value = get_default_value_from_data(val, attribute_type, attribute_size); + current_attribute->default_value.defaultValue = temp_value.defaultValue; + } + current_attribute->default_value_size = attribute_size; + return ESP_OK; +} + static esp_err_t esp_matter_endpoint_disable(esp_matter_endpoint_t *endpoint) { if (!endpoint) { @@ -188,11 +293,6 @@ static esp_err_t esp_matter_endpoint_disable(esp_matter_endpoint_t *endpoint) return ESP_OK; } -extern esp_err_t esp_matter_attribute_get_type_and_val_default(esp_matter_attr_val_t *val, - EmberAfAttributeType *attribute_type, - uint16_t *attribute_size, - EmberAfDefaultOrMinMaxAttributeValue *default_value); - esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) { if (!endpoint) { @@ -212,7 +312,7 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) /* Clusters */ _esp_matter_cluster_t *cluster = current_endpoint->cluster_list; - int cluster_count = esp_matter_cluster_get_count(cluster); + int cluster_count = cluster_get_count(cluster); int cluster_index = 0; DataVersion *data_versions_ptr = (DataVersion *)calloc(1, cluster_count * sizeof(DataVersion)); @@ -253,7 +353,7 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) while (cluster) { /* Attributes */ attribute = cluster->attribute_list; - attribute_count = esp_matter_attribute_get_count(attribute); + attribute_count = attribute_get_count(attribute); attribute_index = 0; matter_attributes = (EmberAfAttributeMetadata *)calloc(1, attribute_count * sizeof(EmberAfAttributeMetadata)); @@ -266,10 +366,9 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) while (attribute) { matter_attributes[attribute_index].attributeId = attribute->attribute_id; matter_attributes[attribute_index].mask = attribute->flags; - esp_matter_attribute_get_type_and_val_default(&attribute->val, - &matter_attributes[attribute_index].attributeType, - &matter_attributes[attribute_index].size, - &matter_attributes[attribute_index].defaultValue); + matter_attributes[attribute_index].defaultValue = attribute->default_value; + get_data_from_attr_val(&attribute->val, &matter_attributes[attribute_index].attributeType, + &matter_attributes[attribute_index].size, NULL); matter_clusters[cluster_index].clusterSize += matter_attributes[attribute_index].size; attribute = attribute->next; @@ -287,7 +386,7 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) /* Client Generated Commands */ command_flag = ESP_MATTER_COMMAND_FLAG_CLIENT_GENERATED; command = cluster->command_list; - command_count = esp_matter_command_get_count(command, command_flag); + command_count = command_get_count(command, command_flag); if (command_count > 0) { command_index = 0; client_generated_command_ids = (CommandId *)calloc(1, (command_count + 1) * sizeof(CommandId)); @@ -309,7 +408,7 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) /* Server Generated Commands */ command_flag = ESP_MATTER_COMMAND_FLAG_SERVER_GENERATED; command = cluster->command_list; - command_count = esp_matter_command_get_count(command, command_flag); + command_count = command_get_count(command, command_flag); if (command_count > 0) { command_index = 0; server_generated_command_ids = (CommandId *)calloc(1, (command_count + 1) * sizeof(CommandId)); @@ -355,7 +454,7 @@ esp_err_t esp_matter_endpoint_enable(esp_matter_endpoint_t *endpoint) endpoint_type->clusterCount = cluster_count; /* Add Endpoint */ - endpoint_index = esp_matter_endpoint_get_next_index(); + endpoint_index = endpoint_get_next_index(); status = emberAfSetDynamicEndpoint(endpoint_index, current_endpoint->endpoint_id, endpoint_type, current_endpoint->device_type_id, 1, chip::Span(data_versions)); @@ -828,6 +927,56 @@ esp_err_t esp_matter_attribute_set_val(esp_matter_attribute_t *attribute, esp_ma return ESP_OK; } +esp_err_t esp_matter_attribute_add_bounds(esp_matter_attribute_t *attribute, esp_matter_attr_val_t min, + esp_matter_attr_val_t max) +{ + if (!attribute) { + ESP_LOGE(TAG, "Attribute cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)attribute; + + /* Check if bounds can be set */ + if (current_attribute->val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING + || current_attribute->val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING + || current_attribute->val.type == ESP_MATTER_VAL_TYPE_ARRAY) { + ESP_LOGE(TAG, "Bounds cannot be set for string/array type attributes"); + return ESP_ERR_INVALID_ARG; + } + if ((current_attribute->val.type != min.type) || (current_attribute->val.type != max.type)) { + ESP_LOGE(TAG, "Cannot set bounds because of val type mismatch: expected: %d, min: %d, max: %d", + current_attribute->val.type, min.type, max.type); + return ESP_ERR_INVALID_ARG; + } + + /* Free the default value before setting the new bounds */ + attribute_free_default_value(attribute); + + /* Allocate and set */ + current_attribute->bounds = (esp_matter_attr_bounds_t *)calloc(1, sizeof(esp_matter_attr_bounds_t)); + if (!current_attribute->bounds) { + ESP_LOGE(TAG, "Could not allocate bounds"); + return ESP_ERR_NO_MEM; + } + memcpy((void *)¤t_attribute->bounds->min, (void *)&min, sizeof(esp_matter_attr_val_t)); + memcpy((void *)¤t_attribute->bounds->max, (void *)&max, sizeof(esp_matter_attr_val_t)); + current_attribute->flags |= ESP_MATTER_ATTRIBUTE_FLAG_MIN_MAX; + + /* Set the default value again after setting the bounds and the flag */ + attribute_set_default_value_from_current_val(attribute); + return ESP_OK; +} + +esp_matter_attr_bounds_t *esp_matter_attribute_get_bounds(esp_matter_attribute_t *attribute) +{ + if (!attribute) { + ESP_LOGE(TAG, "Attribute cannot be NULL"); + return NULL; + } + _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)attribute; + return current_attribute->bounds; +} + esp_matter_command_callback_t esp_matter_command_get_callback(esp_matter_command_t *command) { if (!command) { @@ -873,6 +1022,9 @@ static esp_err_t esp_matter_attribute_delete(esp_matter_attribute_t *attribute) } _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)attribute; + /* Default value needs to be deleted first since it uses the current val. */ + attribute_free_default_value(attribute); + /* Delete val here, if required */ if (current_attribute->val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING || current_attribute->val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING @@ -883,6 +1035,11 @@ static esp_err_t esp_matter_attribute_delete(esp_matter_attribute_t *attribute) } } + /* Free bounds */ + if (current_attribute->bounds) { + free(current_attribute->bounds); + } + /* Free */ free(current_attribute); return ESP_OK; @@ -910,6 +1067,7 @@ esp_matter_attribute_t *esp_matter_attribute_create(esp_matter_cluster_t *cluste attribute->flags = flags; attribute->flags |= ESP_MATTER_ATTRIBUTE_FLAG_EXTERNAL_STORAGE; esp_matter_attribute_set_val((esp_matter_attribute_t *)attribute, &val); + attribute_set_default_value_from_current_val((esp_matter_attribute_t *)attribute); /* Add */ _esp_matter_attribute_t *previous_attribute = NULL; diff --git a/components/esp_matter/esp_matter_core.h b/components/esp_matter/esp_matter_core.h index 74b7d2662..4e85364d9 100644 --- a/components/esp_matter/esp_matter_core.h +++ b/components/esp_matter/esp_matter_core.h @@ -123,6 +123,9 @@ esp_err_t esp_matter_attribute_set_val(esp_matter_attribute_t *attribute, esp_ma esp_err_t esp_matter_attribute_get_val(esp_matter_attribute_t *attribute, esp_matter_attr_val_t *val); esp_err_t esp_matter_attribute_get_val_raw(int endpoint_id, int cluster_id, int attribute_id, uint8_t *value, uint16_t attribute_size); +esp_err_t esp_matter_attribute_add_bounds(esp_matter_attribute_t *attribute, esp_matter_attr_val_t min, + esp_matter_attr_val_t max); +esp_matter_attr_bounds_t *esp_matter_attribute_get_bounds(esp_matter_attribute_t *attribute); /** Command APIs */ esp_matter_command_t *esp_matter_command_create(esp_matter_cluster_t *cluster, int command_id, uint8_t flags,