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); }