From ce9b734d56debbed217ec7ccc791cd2d1174586c Mon Sep 17 00:00:00 2001 From: Chirag Atal Date: Mon, 7 Mar 2022 13:25:11 +0530 Subject: [PATCH] esp_matter_attribute: Fix attribute values for uint16 and strings This includes all the attributes other than uint8. Using memcpy instead of just setting the pointers. Also allocating and freeing the buffers for arrays and strings. --- .../esp_matter/esp_matter_attribute.cpp | 503 +++++++++++------- components/esp_matter/esp_matter_attribute.h | 29 +- components/esp_matter/esp_matter_cluster.cpp | 4 +- components/esp_matter/esp_matter_core.cpp | 33 +- .../rainmaker_light/main/app_rainmaker.cpp | 12 - 5 files changed, 353 insertions(+), 228 deletions(-) diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index ad4508c4d..544bb6815 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -74,39 +74,6 @@ esp_matter_attr_val_t esp_matter_float(float val) return attr_val; } -esp_matter_attr_val_t esp_matter_str(const char *val) -{ - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_STRING, - .val = { - .s = (char *)val, - }, - }; - return attr_val; -} - -esp_matter_attr_val_t esp_matter_json_obj(const char *val) -{ - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_JSON_OBJECT, - .val = { - .s = (char *)val, - }, - }; - return attr_val; -} - -esp_matter_attr_val_t esp_matter_json_array(const char *val) -{ - esp_matter_attr_val_t attr_val = { - .type = ESP_MATTER_VAL_TYPE_JSON_ARRAY, - .val = { - .s = (char *)val, - }, - }; - return attr_val; -} - esp_matter_attr_val_t esp_matter_int8(int8_t val) { esp_matter_attr_val_t attr_val = { @@ -217,45 +184,51 @@ esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val) return attr_val; } -esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t total_size) +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 = total_size, - .n = 0, + .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 total_size, uint16_t count) +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 = total_size, - .n = count, + .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 total_size, uint16_t count) +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 = total_size, + .s = data_size, .n = count, + .t = (uint16_t)(data_size + data_size_len), }, }, }; @@ -285,16 +258,6 @@ esp_err_t esp_matter_attribute_get_type_and_val_default(esp_matter_attr_val_t *v *default_value = (uint8_t *)&val->val.f; break; - case ESP_MATTER_VAL_TYPE_STRING: - *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; - if (val->val.s) { - *attribute_size = strlen(val->val.s); - } else { - *attribute_size = 0; - } - *default_value = (uint8_t *)val->val.s; - break; - case ESP_MATTER_VAL_TYPE_ARRAY: *attribute_type = ZCL_ARRAY_ATTRIBUTE_TYPE; *attribute_size = val->val.a.s; @@ -385,48 +348,72 @@ esp_err_t esp_matter_attribute_get_type_and_val_default(esp_matter_attr_val_t *v return ESP_OK; } -static esp_err_t esp_matter_attribute_get_type_and_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, - uint16_t *attribute_size, uint8_t **value) +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: - *attribute_type = ZCL_BOOLEAN_ATTRIBUTE_TYPE; - *attribute_size = sizeof(bool); - *value = (uint8_t *)&val->val.b; + 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: - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *value = (uint8_t *)&val->val.i; + 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: - *attribute_type = ZCL_SINGLE_ATTRIBUTE_TYPE; - *attribute_size = sizeof(float); - *value = (uint8_t *)&val->val.f; - break; - - case ESP_MATTER_VAL_TYPE_STRING: - *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; - if (val->val.s) { - *attribute_size = strlen(val->val.s); - } else { - *attribute_size = 0; + 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); } - *value = (uint8_t *)val->val.s; break; case ESP_MATTER_VAL_TYPE_ARRAY: - *attribute_type = ZCL_ARRAY_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.s; - *value = (uint8_t *)val->val.a.b; + 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: - *attribute_type = ZCL_CHAR_STRING_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.s; - *value = (uint8_t *)val->val.a.b; + 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: @@ -434,69 +421,137 @@ static esp_err_t esp_matter_attribute_get_type_and_val(esp_matter_attr_val_t *va break; case ESP_MATTER_VAL_TYPE_OCTET_STRING: - *attribute_type = ZCL_OCTET_STRING_ATTRIBUTE_TYPE; - *attribute_size = val->val.a.s; - *value = (uint8_t *)val->val.a.b; + 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: - *attribute_type = ZCL_INT8S_ATTRIBUTE_TYPE; - *attribute_size = sizeof(int8_t); - *value = (uint8_t *)&val->val.i8; + 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: - *attribute_type = ZCL_INT8U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *value = (uint8_t *)&val->val.u8; + 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: - *attribute_type = ZCL_INT16S_ATTRIBUTE_TYPE; - *attribute_size = sizeof(int16_t); - *value = (uint8_t *)&val->val.i16; + 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: - *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *value = (uint8_t *)&val->val.u16; + 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: - *attribute_type = ZCL_INT32U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint32_t); - *value = (uint8_t *)&val->val.u32; + 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: - *attribute_type = ZCL_INT64U_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint64_t); - *value = (uint8_t *)&val->val.u64; + 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: - *attribute_type = ZCL_ENUM8_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *value = (uint8_t *)&val->val.u8; + 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: - *attribute_type = ZCL_BITMAP8_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint8_t); - *value = (uint8_t *)&val->val.u8; + 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: - *attribute_type = ZCL_BITMAP16_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint16_t); - *value = (uint8_t *)&val->val.u16; + 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: - *attribute_type = ZCL_BITMAP32_ATTRIBUTE_TYPE; - *attribute_size = sizeof(uint32_t); - *value = (uint8_t *)&val->val.u32; + 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: @@ -507,66 +562,126 @@ static esp_err_t esp_matter_attribute_get_type_and_val(esp_matter_attr_val_t *va return ESP_OK; } -static esp_matter_attr_val_t esp_matter_attribute_get_attr_val(EmberAfAttributeType attribute_type, - uint16_t attribute_size, uint8_t *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) { switch (attribute_type) { case ZCL_BOOLEAN_ATTRIBUTE_TYPE: - return esp_matter_bool((bool)*value); - break; - - case ZCL_ARRAY_ATTRIBUTE_TYPE: - return esp_matter_array(value, attribute_size, (uint16_t)value[0]); - break; - - case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: - return esp_matter_char_str((char *)&value[1], value[0]); - break; - - case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: - return esp_matter_octet_str(value, attribute_size, (uint16_t)value[0]); - break; - - case ZCL_INT8S_ATTRIBUTE_TYPE: - return esp_matter_int8((int8_t)*value); - break; - - case ZCL_INT8U_ATTRIBUTE_TYPE: - return esp_matter_uint8((uint8_t)*value); - break; - - case ZCL_INT16S_ATTRIBUTE_TYPE: - return esp_matter_int16((int16_t)*value); - break; - - case ZCL_INT16U_ATTRIBUTE_TYPE: - return esp_matter_uint16((uint16_t)*value); - break; - - case ZCL_INT32U_ATTRIBUTE_TYPE: - return esp_matter_uint32((uint32_t)*value); - break; - - case ZCL_INT64U_ATTRIBUTE_TYPE: - return esp_matter_uint64((uint64_t)*value); - break; - - case ZCL_ENUM8_ATTRIBUTE_TYPE: - return esp_matter_enum8((uint8_t)*value); - break; - - case ZCL_BITMAP8_ATTRIBUTE_TYPE: - return esp_matter_bitmap8((uint8_t)*value); - break; - - case ZCL_BITMAP16_ATTRIBUTE_TYPE: - return esp_matter_bitmap16((uint16_t)*value); - break; - - default: - return esp_matter_invalid(NULL); + { + 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) @@ -580,10 +695,6 @@ void esp_matter_attribute_val_print(int endpoint_id, int cluster_id, int attribu } 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_STRING || val.type == ESP_MATTER_VAL_TYPE_JSON_OBJECT || - val.type == ESP_MATTER_VAL_TYPE_JSON_ARRAY) { - ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %s **********", endpoint_id, - cluster_id, attribute_id, val.val.s); } 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); @@ -596,6 +707,9 @@ void esp_matter_attribute_val_print(int endpoint_id, int cluster_id, int attribu } 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); @@ -625,10 +739,18 @@ esp_err_t esp_matter_attribute_get_val_raw(int endpoint_id, int cluster_id, int esp_err_t esp_matter_attribute_update(int endpoint_id, int cluster_id, int attribute_id, esp_matter_attr_val_t val) { + /* Get size */ EmberAfAttributeType attribute_type = 0; uint16_t attribute_size = 0; - uint8_t *value = NULL; - esp_matter_attribute_get_type_and_val(&val, &attribute_type, &attribute_size, &value); + 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"); + return ESP_ERR_NO_MEM; + } + get_data_from_attr_val(&val, &attribute_type, &attribute_size, value); /* Update matter */ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; @@ -636,9 +758,11 @@ esp_err_t esp_matter_attribute_update(int endpoint_id, int cluster_id, int attri 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); return ESP_FAIL; } } + free(value); return ESP_OK; } @@ -648,7 +772,8 @@ Status MatterPreAttributeChangeCallback(const chip::app::ConcreteAttributePath & int endpoint_id = path.mEndpointId; int cluster_id = path.mClusterId; int attribute_id = path.mAttributeId; - esp_matter_attr_val_t val = esp_matter_attribute_get_attr_val(type, size, value); + 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); @@ -670,7 +795,8 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &p int endpoint_id = path.mEndpointId; int cluster_id = path.mClusterId; int attribute_id = path.mAttributeId; - esp_matter_attr_val_t val = esp_matter_attribute_get_attr_val(type, size, value); + 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) { @@ -694,18 +820,20 @@ EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint_id, Clust esp_matter_attribute_t *attribute = esp_matter_attribute_get(cluster, attribute_id); esp_matter_attr_val_t val = esp_matter_attribute_get_val(attribute); - /* Convert */ - EmberAfAttributeType attribute_type = 0; - uint16_t attribute_size = 0; - uint8_t *value = NULL; - esp_matter_attribute_get_type_and_val(&val, &attribute_type, &attribute_size, &value); + /* 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 */ - *buffer = *value; + get_data_from_attr_val(&val, NULL, &attribute_size, buffer); return EMBER_ZCL_STATUS_SUCCESS; } @@ -721,19 +849,14 @@ EmberAfStatus emberAfExternalAttributeWriteCallback(EndpointId endpoint_id, Clus 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_attribute_get_val(attribute); - /* Convert */ - EmberAfAttributeType attribute_type = 0; - uint16_t attribute_size = 0; - uint8_t *value = NULL; - esp_matter_attribute_get_type_and_val(&val, &attribute_type, &attribute_size, &value); + /* 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); - /* Convert back */ - value = buffer; - val = esp_matter_attribute_get_attr_val(attribute_type, attribute_size, value); - - /* Update value */ + /* Update val */ esp_matter_attribute_set_val(attribute, val); return EMBER_ZCL_STATUS_SUCCESS; } diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 96af68da0..b53094029 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -30,8 +30,6 @@ typedef enum { ESP_MATTER_VAL_TYPE_INTEGER, /** Floating point number */ ESP_MATTER_VAL_TYPE_FLOAT, - /** NULL terminated string */ - ESP_MATTER_VAL_TYPE_STRING, /** Array Eg. [1,2,3] */ ESP_MATTER_VAL_TYPE_ARRAY, /** Byte String Eg. "123" */ @@ -60,10 +58,6 @@ typedef enum { ESP_MATTER_VAL_TYPE_BITMAP16, /** 32 bit bitmap */ ESP_MATTER_VAL_TYPE_BITMAP32, - /** NULL terminated JSON Object string Eg. "{\"name\":\"value\"}" */ - ESP_MATTER_VAL_TYPE_JSON_OBJECT, - /** NULL terminated JSON Array string Eg. "[1,2,3]" */ - ESP_MATTER_VAL_TYPE_JSON_ARRAY, } esp_matter_val_type_t; /* ESP Matter Value */ @@ -74,8 +68,6 @@ typedef union { int i; /** Float */ float f; - /** NULL terminated string. It should stay allocated throughout the lifetime of the device. */ - char *s; /** 8 bit signed integer */ int8_t i8; /** 8 bit unsigned integer */ @@ -92,10 +84,12 @@ typedef union { struct { /** Buffer */ uint8_t *b; - /** Total size */ + /** Data size */ uint16_t s; - /** Total count */ + /** Data count */ uint16_t n; + /** Total size */ + uint16_t t; } a; /** Pointer */ void *p; @@ -122,15 +116,6 @@ esp_matter_attr_val_t esp_matter_int(int val); /** Float */ esp_matter_attr_val_t esp_matter_float(float val); -/** String */ -esp_matter_attr_val_t esp_matter_str(const char *val); - -/** JSON object string */ -esp_matter_attr_val_t esp_matter_json_obj(const char *val); - -/** JSON array string */ -esp_matter_attr_val_t esp_matter_json_array(const char *val); - /** 8 bit integer */ esp_matter_attr_val_t esp_matter_int8(int8_t val); @@ -162,13 +147,13 @@ esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val); 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 total_size); +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 total_size, uint16_t count); +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 total_size, uint16_t count); +esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count); /** Attribute update * diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index bfd1cbdc3..1c6cd20a7 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -358,7 +358,7 @@ esp_matter_cluster_t *esp_matter_cluster_create_ota_requestor(esp_matter_endpoin 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), 0)); + 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, @@ -448,7 +448,7 @@ esp_matter_cluster_t *esp_matter_cluster_create_network_commissioning(esp_matter 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), 0)); + 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)); diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index d5321a33c..c6caef65a 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -595,7 +595,28 @@ esp_err_t esp_matter_attribute_set_val(esp_matter_attribute_t *attribute, esp_ma return ESP_FAIL; } _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)attribute; - current_attribute->val = val; + if (val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING || val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING + || val.type == ESP_MATTER_VAL_TYPE_ARRAY) { + /* Free old buf */ + if (current_attribute->val.val.a.b) { + free(current_attribute->val.val.a.b); + } + if (val.val.a.s > 0) { + /* Alloc new buf */ + uint8_t *new_buf = (uint8_t *)calloc(1, val.val.a.s); + if (!new_buf) { + ESP_LOGE(TAG, "Could not allocate new buffer"); + return ESP_ERR_NO_MEM; + } + /* Copy to new buf and assign */ + 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"); + val.val.a.b = NULL; + } + } + memcpy((void *)¤t_attribute->val, (void *)&val, sizeof(esp_matter_attr_val_t)); return ESP_OK; } @@ -645,6 +666,14 @@ static esp_err_t esp_matter_attribute_delete(esp_matter_attribute_t *attribute) _esp_matter_attribute_t *current_attribute = (_esp_matter_attribute_t *)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 + || current_attribute->val.type == ESP_MATTER_VAL_TYPE_ARRAY) { + /* Free buf */ + if (current_attribute->val.val.a.b) { + free(current_attribute->val.val.a.b); + } + } /* Free */ free(current_attribute); @@ -672,7 +701,7 @@ esp_matter_attribute_t *esp_matter_attribute_create(esp_matter_cluster_t *cluste attribute->attribute_id = attribute_id; attribute->flags = flags; attribute->flags |= ESP_MATTER_ATTRIBUTE_FLAG_EXTERNAL_STORAGE; - attribute->val = val; + esp_matter_attribute_set_val((esp_matter_attribute_t *)attribute, val); /* Add */ _esp_matter_attribute_t *previous_attribute = NULL; diff --git a/examples/rainmaker_light/main/app_rainmaker.cpp b/examples/rainmaker_light/main/app_rainmaker.cpp index a91a22450..8bdeaf2b9 100644 --- a/examples/rainmaker_light/main/app_rainmaker.cpp +++ b/examples/rainmaker_light/main/app_rainmaker.cpp @@ -203,12 +203,6 @@ static esp_rmaker_param_val_t app_rainmaker_get_rmaker_val(esp_matter_attr_val_t return esp_rmaker_int(val.val.i); } else if (val.type == ESP_MATTER_VAL_TYPE_FLOAT) { return esp_rmaker_float(val.val.f); - } else if (val.type == ESP_MATTER_VAL_TYPE_STRING) { - return esp_rmaker_str(val.val.s); - } else if (val.type == ESP_MATTER_VAL_TYPE_JSON_OBJECT) { - return esp_rmaker_obj(val.val.s); - } else if (val.type == ESP_MATTER_VAL_TYPE_JSON_ARRAY) { - return esp_rmaker_array(val.val.s); } else if (val.type == ESP_MATTER_VAL_TYPE_UINT8) { return esp_rmaker_int(val.val.u8); } else if (val.type == ESP_MATTER_VAL_TYPE_INT16) { @@ -229,12 +223,6 @@ static esp_matter_attr_val_t app_rainmaker_get_matter_val(esp_rmaker_param_val_t return esp_matter_int(val.val.i); } else if (val.type == RMAKER_VAL_TYPE_FLOAT) { return esp_matter_float(val.val.f); - } else if (val.type == RMAKER_VAL_TYPE_STRING) { - return esp_matter_str(val.val.s); - } else if (val.type == RMAKER_VAL_TYPE_OBJECT) { - return esp_matter_json_obj(val.val.s); - } else if (val.type == RMAKER_VAL_TYPE_ARRAY) { - return esp_matter_json_array(val.val.s); } else { ESP_LOGE(TAG, "Invalid val type: %d", val.type); }