mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
components/esp_matter: extend set val for internally managed writable
attributes - re-implemented the set_val to set them using the TLV buffer for an attribute using DataModelProvider::WriteAttribute() API. - renamed older set_val() to set_val_internal() and made it private. - changed the set_val's occurances with set_val_internal inside the component. Since our sdk should not be worrying about getting data from the internally managed attributes, its safe to use the set_val_internal(). - updated release notes
This commit is contained in:
@@ -1,3 +1,18 @@
|
|||||||
|
# 27-Nov-2025
|
||||||
|
### Feature: attribute::get_val() and attribute::set_val() APIs
|
||||||
|
|
||||||
|
- `attribute::get_val()`
|
||||||
|
- API now supports getting the value of internally managed attributes of primitive data types.
|
||||||
|
- Complex types are not supported yet, eg: (Array, Struct, List, etc.)
|
||||||
|
|
||||||
|
- `attribute::set_val()`
|
||||||
|
- API now supports setting the value of internally managed attributes which are writable and of data type primitive.
|
||||||
|
- Attributes which are not writable but managed internally are not supported yet
|
||||||
|
- Complex types are not supported yet, eg: (Array, Struct, List, etc.)
|
||||||
|
|
||||||
|
- For unsupported attributes, the APIs will return `ESP_ERR_NOT_SUPPORTED`,
|
||||||
|
please use the cluster-specific setter APIs.
|
||||||
|
|
||||||
## 21-Nov-2025
|
## 21-Nov-2025
|
||||||
### API Changes: Attribute Creation Function Names
|
### API Changes: Attribute Creation Function Names
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <esp_matter_console.h>
|
#include <esp_matter_console.h>
|
||||||
#include <esp_matter_core.h>
|
#include <esp_matter_core.h>
|
||||||
#include <esp_matter_mem.h>
|
#include <esp_matter_mem.h>
|
||||||
|
#include <esp_matter_data_model_priv.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <app/util/attribute-storage.h>
|
#include <app/util/attribute-storage.h>
|
||||||
@@ -641,7 +642,7 @@ esp_err_t update(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_i
|
|||||||
/* Here, the val_print function gets called on attribute write.*/
|
/* Here, the val_print function gets called on attribute write.*/
|
||||||
attribute::val_print(endpoint_id, cluster_id, attribute_id, val, false);
|
attribute::val_print(endpoint_id, cluster_id, attribute_id, val, false);
|
||||||
|
|
||||||
esp_err_t err = attribute::set_val(attr, val);
|
esp_err_t err = attribute::set_val_internal(attr, val);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
data_model::provider::get_instance().Temporary_ReportAttributeChanged(
|
data_model::provider::get_instance().Temporary_ReportAttributeChanged(
|
||||||
chip::app::AttributePathParams(endpoint_id, cluster_id, attribute_id));
|
chip::app::AttributePathParams(endpoint_id, cluster_id, attribute_id));
|
||||||
@@ -667,7 +668,7 @@ esp_err_t report(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_i
|
|||||||
/* Here, the val_print function gets called on attribute write.*/
|
/* Here, the val_print function gets called on attribute write.*/
|
||||||
attribute::val_print(endpoint_id, cluster_id, attribute_id, val, false);
|
attribute::val_print(endpoint_id, cluster_id, attribute_id, val, false);
|
||||||
|
|
||||||
esp_err_t err = attribute::set_val(attr, val, false);
|
esp_err_t err = attribute::set_val_internal(attr, val, false);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
/* Report attribute */
|
/* Report attribute */
|
||||||
MatterReportingAttributeChangeCallback(endpoint_id, cluster_id, attribute_id);
|
MatterReportingAttributeChangeCallback(endpoint_id, cluster_id, attribute_id);
|
||||||
|
|||||||
@@ -412,6 +412,7 @@ esp_err_t update(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_i
|
|||||||
* This API reports the attribute value.
|
* This API reports the attribute value.
|
||||||
* After this API is called, the application doesn't gets the attribute update callback with `PRE_UPDATE` or `POST_UPDATE`, the
|
* After this API is called, the application doesn't gets the attribute update callback with `PRE_UPDATE` or `POST_UPDATE`, the
|
||||||
* attribute is updated in the database.
|
* attribute is updated in the database.
|
||||||
|
* This also marks the attribute as dirty, so that it can be reported in the next subscription report.
|
||||||
*
|
*
|
||||||
* @param[in] endpoint_id Endpoint ID of the attribute.
|
* @param[in] endpoint_id Endpoint ID of the attribute.
|
||||||
* @param[in] cluster_id Cluster ID of the attribute.
|
* @param[in] cluster_id Cluster ID of the attribute.
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ inline bool is_wildcard_endpoint_id(uint16_t endpoint_id)
|
|||||||
// We allocate this large scoped buffer to read the attribute as the TLV data
|
// We allocate this large scoped buffer to read the attribute as the TLV data
|
||||||
// This is enough to store the TLV encoded buffer for a primitive type of data
|
// This is enough to store the TLV encoded buffer for a primitive type of data
|
||||||
const uint32_t k_max_tlv_size_to_read_attribute_value = 512;
|
const uint32_t k_max_tlv_size_to_read_attribute_value = 512;
|
||||||
|
const uint32_t k_max_tlv_size_to_write_attribute_value = 512;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -544,7 +545,7 @@ attribute_t *create(cluster_t *cluster, uint32_t attribute_id, uint16_t flags, e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!attribute_updated) {
|
if (!attribute_updated) {
|
||||||
set_val((attribute_t *)attribute, &val);
|
set_val_internal((attribute_t *)attribute, &val, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,13 +639,14 @@ static void deferred_attribute_write(chip::System::Layer *layer, void *attribute
|
|||||||
{current_attribute->attribute_val_type, current_attribute->attribute_val});
|
{current_attribute->attribute_val_type, current_attribute->attribute_val});
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t set_val(attribute_t *attribute, esp_matter_attr_val_t *val, bool call_callbacks)
|
esp_err_t set_val_internal(attribute_t *attribute, esp_matter_attr_val_t *val, bool call_callbacks)
|
||||||
{
|
{
|
||||||
VerifyOrReturnError(attribute && val, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Attribute and val cannot be NULL"));
|
VerifyOrReturnError(attribute && val, ESP_ERR_INVALID_ARG);
|
||||||
_attribute_t *current_attribute = (_attribute_t *)attribute;
|
_attribute_t *current_attribute = (_attribute_t *)attribute;
|
||||||
|
|
||||||
ESP_RETURN_ON_FALSE(!(current_attribute->flags & ATTRIBUTE_FLAG_MANAGED_INTERNALLY), ESP_ERR_NOT_SUPPORTED, TAG,
|
ESP_RETURN_ON_FALSE(!(current_attribute->flags & ATTRIBUTE_FLAG_MANAGED_INTERNALLY), ESP_ERR_NOT_SUPPORTED, TAG,
|
||||||
"Attribute is not managed by esp matter data model");
|
"Attribute is not managed by esp matter data model");
|
||||||
|
|
||||||
VerifyOrReturnError(current_attribute->attribute_val_type == val->type, ESP_ERR_INVALID_ARG,
|
VerifyOrReturnError(current_attribute->attribute_val_type == val->type, ESP_ERR_INVALID_ARG,
|
||||||
ESP_LOGE(TAG, "Different value type : Expected Type : %u Attempted Type: %u",
|
ESP_LOGE(TAG, "Different value type : Expected Type : %u Attempted Type: %u",
|
||||||
current_attribute->attribute_val_type, val->type));
|
current_attribute->attribute_val_type, val->type));
|
||||||
@@ -817,7 +819,7 @@ static esp_err_t get_val_from_tlv_data(const uint8_t *tlv_data, uint32_t tlv_len
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to find the cluster_id and attribute_id for internally managed attributes
|
// Helper function to find the cluster_id and attribute_id for internally managed attributes
|
||||||
static esp_err_t find_cluster_and_endpoint_id_for_internally_managed_attribute(_attribute_base_t *attribute_base,
|
static esp_err_t find_cluster_and_endpoint_id_for_internally_managed_attribute(const _attribute_base_t *attribute_base,
|
||||||
uint16_t &out_endpoint_id,
|
uint16_t &out_endpoint_id,
|
||||||
uint32_t &out_cluster_id)
|
uint32_t &out_cluster_id)
|
||||||
{
|
{
|
||||||
@@ -883,31 +885,32 @@ esp_err_t get_val(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_
|
|||||||
return get_val_from_tlv_data(scoped_buf.Get(), writer.GetLengthWritten(), val);
|
return get_val_from_tlv_data(scoped_buf.Get(), writer.GetLengthWritten(), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t get_path_from_attribute_handle(const _attribute_t *attribute, uint16_t &endpoint_id,
|
||||||
|
uint32_t &cluster_id, uint32_t &attribute_id)
|
||||||
|
{
|
||||||
|
attribute_id = attribute->attribute_id;
|
||||||
|
if (attribute->flags & ATTRIBUTE_FLAG_MANAGED_INTERNALLY) {
|
||||||
|
// for connectedhomeip managed attributes, we need to find the cluster and endpoint id
|
||||||
|
return find_cluster_and_endpoint_id_for_internally_managed_attribute(attribute, endpoint_id, cluster_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// in case of esp-matter managed attributes, we can directly use the endpoint and cluster id
|
||||||
|
endpoint_id = attribute->endpoint_id;
|
||||||
|
cluster_id = attribute->cluster_id;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t get_val(attribute_t *attribute, esp_matter_attr_val_t *val)
|
esp_err_t get_val(attribute_t *attribute, esp_matter_attr_val_t *val)
|
||||||
{
|
{
|
||||||
VerifyOrReturnError(attribute && val, ESP_ERR_INVALID_ARG);
|
VerifyOrReturnError(attribute && val, ESP_ERR_INVALID_ARG);
|
||||||
_attribute_t *current_attribute = (_attribute_t *)attribute;
|
_attribute_t *current_attribute = (_attribute_t *)attribute;
|
||||||
|
|
||||||
uint32_t attribute_id = current_attribute->attribute_id;
|
|
||||||
uint32_t cluster_id = chip::kInvalidClusterId;
|
|
||||||
uint16_t endpoint_id = chip::kInvalidEndpointId;
|
uint16_t endpoint_id = chip::kInvalidEndpointId;
|
||||||
|
uint32_t cluster_id = chip::kInvalidClusterId;
|
||||||
|
uint32_t attribute_id = chip::kInvalidAttributeId;
|
||||||
|
|
||||||
if (current_attribute->flags & ATTRIBUTE_FLAG_MANAGED_INTERNALLY) {
|
esp_err_t err = get_path_from_attribute_handle(current_attribute, endpoint_id, cluster_id, attribute_id);
|
||||||
// for internally managed attributes, we need to find the cluster and endpoint id
|
VerifyOrReturnError(err == ESP_OK, err);
|
||||||
esp_err_t err = find_cluster_and_endpoint_id_for_internally_managed_attribute(current_attribute,
|
|
||||||
endpoint_id, cluster_id);
|
|
||||||
if (err != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Failed to get cluster and ep id for attribute, err: %d", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster_id = cluster_id;
|
|
||||||
attribute_id = attribute_id;
|
|
||||||
} else {
|
|
||||||
// in case of externally managed attributes, we can directly use the endpoint and cluster id
|
|
||||||
endpoint_id = current_attribute->endpoint_id;
|
|
||||||
cluster_id = current_attribute->cluster_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return get_val(endpoint_id, cluster_id, attribute_id, val);
|
return get_val(endpoint_id, cluster_id, attribute_id, val);
|
||||||
}
|
}
|
||||||
@@ -936,6 +939,101 @@ esp_matter_val_type_t get_val_type(uint16_t endpoint_id, uint32_t cluster_id, ui
|
|||||||
return get_val_type(get(endpoint_id, cluster_id, attribute_id));
|
return get_val_type(get(endpoint_id, cluster_id, attribute_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function: Set value via WriteAttribute with kInternal flag (for SCI/AAI writable attributes)
|
||||||
|
static esp_err_t set_val_via_write_attribute(uint16_t endpoint_id, uint32_t cluster_id,
|
||||||
|
uint32_t attribute_id, esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
chip::Platform::ScopedMemoryBuffer<uint8_t> tlv_buffer;
|
||||||
|
tlv_buffer.Calloc(k_max_tlv_size_to_write_attribute_value);
|
||||||
|
VerifyOrReturnError(!tlv_buffer.IsNull(), ESP_ERR_NO_MEM);
|
||||||
|
|
||||||
|
chip::TLV::TLVWriter writer;
|
||||||
|
writer.Init(tlv_buffer.Get(), k_max_tlv_size_to_write_attribute_value);
|
||||||
|
|
||||||
|
// Encoding is within a structure:
|
||||||
|
// - BEGIN_STRUCT
|
||||||
|
// - 1: <encoded value>
|
||||||
|
// - END_STRUCT
|
||||||
|
chip::TLV::TLVType outerContainer;
|
||||||
|
VerifyOrReturnError(writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerContainer) == CHIP_NO_ERROR, ESP_FAIL);
|
||||||
|
data_model::attribute_data_encode_buffer encode_buffer(*val);
|
||||||
|
VerifyOrReturnError(encode_buffer.Encode(writer, chip::TLV::ContextTag(1)) == CHIP_NO_ERROR, ESP_FAIL);
|
||||||
|
VerifyOrReturnError(writer.EndContainer(outerContainer) == CHIP_NO_ERROR, ESP_FAIL);
|
||||||
|
VerifyOrReturnError(writer.Finalize() == CHIP_NO_ERROR, ESP_FAIL);
|
||||||
|
|
||||||
|
// position the reader inside the buffer, on the encoded value
|
||||||
|
chip::TLV::TLVReader reader;
|
||||||
|
reader.Init(tlv_buffer.Get(), writer.GetLengthWritten());
|
||||||
|
VerifyOrReturnError(reader.Next() == CHIP_NO_ERROR, ESP_FAIL);
|
||||||
|
VerifyOrReturnError(reader.EnterContainer(outerContainer) == CHIP_NO_ERROR, ESP_FAIL);
|
||||||
|
VerifyOrReturnError(reader.Next() == CHIP_NO_ERROR, ESP_FAIL);
|
||||||
|
|
||||||
|
// create write request and call WriteAttribute through the provider
|
||||||
|
chip::app::DataModel::WriteAttributeRequest request;
|
||||||
|
request.path = chip::app::ConcreteDataAttributePath(endpoint_id, cluster_id, attribute_id);
|
||||||
|
request.operationFlags.Set(chip::app::DataModel::OperationFlags::kInternal);
|
||||||
|
|
||||||
|
chip::Access::SubjectDescriptor subjectDescriptor;
|
||||||
|
chip::app::AttributeValueDecoder decoder(reader, subjectDescriptor);
|
||||||
|
|
||||||
|
// we need to ensure locks are in place to avoid assertion errors
|
||||||
|
esp_matter::lock::chip_stack_lock(portMAX_DELAY);
|
||||||
|
|
||||||
|
chip::app::DataModel::ActionReturnStatus status =
|
||||||
|
esp_matter::data_model::provider::get_instance().WriteAttribute(request, decoder);
|
||||||
|
|
||||||
|
esp_matter::lock::chip_stack_unlock();
|
||||||
|
|
||||||
|
if (status.IsError()) {
|
||||||
|
chip::app::DataModel::ActionReturnStatus::StringStorage storage;
|
||||||
|
ESP_LOGE(TAG, "WriteAttribute failed with status: %s", status.c_str(storage));
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t set_val(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val, bool call_callbacks)
|
||||||
|
{
|
||||||
|
VerifyOrReturnError(val && val->type != ESP_MATTER_VAL_TYPE_INVALID, ESP_ERR_INVALID_ARG);
|
||||||
|
VerifyOrReturnError(val->type != ESP_MATTER_VAL_TYPE_ARRAY, ESP_ERR_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
attribute_t *attr = get(endpoint_id, cluster_id, attribute_id);
|
||||||
|
VerifyOrReturnError(attr, ESP_ERR_NOT_FOUND);
|
||||||
|
VerifyOrReturnError(get_val_type(attr) == val->type, ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
|
uint16_t flags = get_flags(attr);
|
||||||
|
|
||||||
|
if (!(flags & ATTRIBUTE_FLAG_MANAGED_INTERNALLY)) {
|
||||||
|
// this updates the value of attribute in the esp-matter storage
|
||||||
|
return attribute::set_val_internal(attr, val, call_callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can use DataModelProvider::WriteAttribute API for writable attributes
|
||||||
|
if (flags & ATTRIBUTE_FLAG_WRITABLE) {
|
||||||
|
return set_val_via_write_attribute(endpoint_id, cluster_id, attribute_id, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: If not writable, we could use the cluster-specific setter API to update the value
|
||||||
|
// with the code-driven effort, we can get the cluster object and call the setter API
|
||||||
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t set_val(attribute_t *attribute, esp_matter_attr_val_t *val, bool call_callbacks)
|
||||||
|
{
|
||||||
|
VerifyOrReturnError(attribute && val, ESP_ERR_INVALID_ARG);
|
||||||
|
_attribute_t *current_attribute = (_attribute_t *)attribute;
|
||||||
|
|
||||||
|
uint16_t endpoint_id = chip::kInvalidEndpointId;
|
||||||
|
uint32_t cluster_id = chip::kInvalidClusterId;
|
||||||
|
uint32_t attribute_id = chip::kInvalidAttributeId;
|
||||||
|
|
||||||
|
esp_err_t err = get_path_from_attribute_handle(current_attribute, endpoint_id, cluster_id, attribute_id);
|
||||||
|
VerifyOrReturnError(err == ESP_OK, err);
|
||||||
|
|
||||||
|
return set_val(endpoint_id, cluster_id, attribute_id, val, call_callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t add_bounds(attribute_t *attribute, esp_matter_attr_val_t min, esp_matter_attr_val_t max)
|
esp_err_t add_bounds(attribute_t *attribute, esp_matter_attr_val_t min, esp_matter_attr_val_t max)
|
||||||
{
|
{
|
||||||
VerifyOrReturnError(attribute, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Attribute cannot be NULL"));
|
VerifyOrReturnError(attribute, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Attribute cannot be NULL"));
|
||||||
|
|||||||
@@ -884,11 +884,37 @@ attribute_t *get_next(attribute_t *attribute);
|
|||||||
*/
|
*/
|
||||||
uint32_t get_id(attribute_t *attribute);
|
uint32_t get_id(attribute_t *attribute);
|
||||||
|
|
||||||
/** Set attribute val
|
/** Set attribute value
|
||||||
*
|
*
|
||||||
* Set/Update the value of the attribute (has `ATTRIBUTE_FLAG_EXTERNAL_STORAGE` flag) in the database.
|
* This API is a unified API that works across all storage types.
|
||||||
|
* It supports writing attributes whose value storage is managed by esp matter data model
|
||||||
|
* as well as writable attributes that are not managed by esp matter data model.
|
||||||
|
* Right now this only works for primitive types and strings.
|
||||||
|
*
|
||||||
|
* TODO: support writing complex types (arrays, structs, lists)
|
||||||
|
* TODO: support remaining attributes by using cluster-specific setter APIs
|
||||||
|
*
|
||||||
|
* This API uses the DataModelProvider::WriteAttribute API to write the value of the attribute,
|
||||||
|
* tries to write value to the supported storages.
|
||||||
|
*
|
||||||
|
* @note: For unsupported cases, this API will return ESP_ERR_NOT_SUPPORTED, please use
|
||||||
|
* cluster-specific setter APIs for complex types (arrays, structs, lists) and remaining attributes.
|
||||||
*
|
*
|
||||||
* @note: Once `esp_matter::start()` is done, `attribute::update()` should be used to update the attribute value.
|
* @note: Once `esp_matter::start()` is done, `attribute::update()` should be used to update the attribute value.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint id.
|
||||||
|
* @param[in] cluster_id Cluster id.
|
||||||
|
* @param[in] attribute_id Attribute id.
|
||||||
|
* @param[in] val Pointer to `esp_matter_attr_val_t` containing the new value.
|
||||||
|
* @param[in] call_callbacks Whether to call attribute change pre/post callbacks.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_val(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id,
|
||||||
|
esp_matter_attr_val_t *val, bool call_callbacks = true);
|
||||||
|
|
||||||
|
/** Set attribute val, similar to set_val but with attribute handle
|
||||||
*
|
*
|
||||||
* @param[in] attribute Attribute handle.
|
* @param[in] attribute Attribute handle.
|
||||||
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ static esp_err_t update_feature_map(cluster_t *cluster, uint32_t value)
|
|||||||
VerifyOrReturnError(attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
VerifyOrReturnError(attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
||||||
val.val.u32 |= value;
|
val.val.u32 |= value;
|
||||||
/* Here we can't call attribute::update() since the chip stack would not have started yet, since we are
|
/* Here we can't call attribute::update() since the chip stack would not have started yet, since we are
|
||||||
still creating the data model. So, we are directly using attribute::set_val(). */
|
still creating the data model. So, we are directly using attribute::set_val_internal(). */
|
||||||
return attribute::set_val(attribute, &val);
|
return attribute::set_val_internal(attribute, &val, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_feature_map_value(cluster_t *cluster)
|
static uint32_t get_feature_map_value(cluster_t *cluster)
|
||||||
@@ -608,8 +608,8 @@ static esp_err_t update_color_capability(cluster_t *cluster, uint16_t value)
|
|||||||
VerifyOrReturnError(esp_matter::attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
VerifyOrReturnError(esp_matter::attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
||||||
val.val.u16 |= value;
|
val.val.u16 |= value;
|
||||||
/* Here we can't call attribute::update() since the chip stack would not have started yet, since we are
|
/* Here we can't call attribute::update() since the chip stack would not have started yet, since we are
|
||||||
still creating the data model. So, we are directly using attribute::set_val(). */
|
still creating the data model. So, we are directly using attribute::set_val_internal(). */
|
||||||
return esp_matter::attribute::set_val(attribute, &val);
|
return esp_matter::attribute::set_val_internal(attribute, &val, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace hue_saturation {
|
namespace hue_saturation {
|
||||||
@@ -827,7 +827,7 @@ esp_err_t add(cluster_t *cluster, config_t *config)
|
|||||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||||
VerifyOrReturnError(esp_matter::attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
VerifyOrReturnError(esp_matter::attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
||||||
val.val.u8 = val.val.u8 | set_third_bit;
|
val.val.u8 = val.val.u8 | set_third_bit;
|
||||||
return esp_matter::attribute::set_val(attribute, &val);
|
return esp_matter::attribute::set_val_internal(attribute, &val, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGE(TAG, "Cluster shall support Lift feature");
|
ESP_LOGE(TAG, "Cluster shall support Lift feature");
|
||||||
@@ -917,7 +917,7 @@ esp_err_t add(cluster_t *cluster, config_t *config)
|
|||||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||||
VerifyOrReturnError(esp_matter::attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
VerifyOrReturnError(esp_matter::attribute::get_val_internal(attribute, &val) == ESP_OK, ESP_FAIL);
|
||||||
val.val.u8 = val.val.u8 | set_fourth_bit;
|
val.val.u8 = val.val.u8 | set_fourth_bit;
|
||||||
return esp_matter::attribute::set_val(attribute, &val);
|
return esp_matter::attribute::set_val_internal(attribute, &val, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGE(TAG, "Cluster shall support Tilt feature");
|
ESP_LOGE(TAG, "Cluster shall support Tilt feature");
|
||||||
|
|||||||
@@ -52,6 +52,17 @@ namespace attribute {
|
|||||||
*/
|
*/
|
||||||
esp_err_t get_val_internal(attribute_t *attribute, esp_matter_attr_val_t *val);
|
esp_err_t get_val_internal(attribute_t *attribute, esp_matter_attr_val_t *val);
|
||||||
|
|
||||||
|
/** Set the attribute value in the esp-matter storage
|
||||||
|
*
|
||||||
|
* @param[in] attribute Attribute handle.
|
||||||
|
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||||
|
* @param[in] call_callbacks Whether to call attribute change pre/post callbacks.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t set_val_internal(attribute_t *attribute, esp_matter_attr_val_t *val, bool call_callbacks = true);
|
||||||
|
|
||||||
} // namespace attribute
|
} // namespace attribute
|
||||||
|
|
||||||
} // namespace esp_matter
|
} // namespace esp_matter
|
||||||
|
|||||||
@@ -1048,7 +1048,7 @@ Status emberAfWriteAttribute(const chip::app::ConcreteAttributePath &path, const
|
|||||||
if (status != Status::Success) {
|
if (status != Status::Success) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
esp_err_t err = esp_matter::attribute::set_val(attribute, &val);
|
esp_err_t err = esp_matter::attribute::set_val_internal(attribute, &val);
|
||||||
if (err != ESP_OK && err != ESP_ERR_NOT_FINISHED) {
|
if (err != ESP_OK && err != ESP_ERR_NOT_FINISHED) {
|
||||||
status = Status::Failure;
|
status = Status::Failure;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user