mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
Merge branch 'fix_endpoint_report' into 'main'
components/esp_matter: report attribute change in endpoint::enable and disable See merge request app-frameworks/esp-matter!1427
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
# 4-Feb-2026
|
||||||
|
### API Changes
|
||||||
|
- Removed APIs: `plugin_init_callback_common()`, `add_bounds_callback_common()` and `delegate_init_callback_common()`.
|
||||||
|
|
||||||
# 27-Nov-2025
|
# 27-Nov-2025
|
||||||
### Feature: attribute::get_val() and attribute::set_val() APIs
|
### Feature: attribute::get_val() and attribute::set_val() APIs
|
||||||
|
|
||||||
|
|||||||
@@ -121,20 +121,6 @@ cluster_t * ABORT_CLUSTER_CREATE(cluster_t *cluster)
|
|||||||
}
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
void delegate_init_callback_common(endpoint_t *endpoint)
|
|
||||||
{
|
|
||||||
uint16_t endpoint_id = endpoint::get_id(endpoint);
|
|
||||||
cluster_t *cluster = get_first(endpoint);
|
|
||||||
while (cluster) {
|
|
||||||
/* Delegate server init callback */
|
|
||||||
delegate_init_callback_t delegate_init_callback = get_delegate_init_callback(cluster);
|
|
||||||
if (delegate_init_callback) {
|
|
||||||
delegate_init_callback(get_delegate_impl(cluster), endpoint_id);
|
|
||||||
}
|
|
||||||
cluster = get_next(cluster);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster_t *create_default_binding_cluster(endpoint_t *endpoint)
|
cluster_t *create_default_binding_cluster(endpoint_t *endpoint)
|
||||||
{
|
{
|
||||||
/* Don't create binding cluster if it already exists on the endpoint */
|
/* Don't create binding cluster if it already exists on the endpoint */
|
||||||
|
|||||||
@@ -213,11 +213,36 @@ esp_err_t read_min_unused_endpoint_id()
|
|||||||
|
|
||||||
namespace endpoint {
|
namespace endpoint {
|
||||||
|
|
||||||
|
static void report_parts_list_change_internal(endpoint_t *endpoint)
|
||||||
|
{
|
||||||
|
chip::EndpointId parent_endpoint_id = endpoint::get_parent_endpoint_id(endpoint);
|
||||||
|
while (parent_endpoint_id != chip::kInvalidEndpointId) {
|
||||||
|
MatterReportingAttributeChangeCallback(parent_endpoint_id, chip::app::Clusters::Descriptor::Id,
|
||||||
|
chip::app::Clusters::Descriptor::Attributes::PartsList::Id);
|
||||||
|
parent_endpoint_id = endpoint::get_parent_endpoint_id(endpoint::get(parent_endpoint_id));
|
||||||
|
}
|
||||||
|
MatterReportingAttributeChangeCallback(/* endpoint = */ 0, chip::app::Clusters::Descriptor::Id,
|
||||||
|
chip::app::Clusters::Descriptor::Attributes::PartsList::Id);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t disable(endpoint_t *endpoint)
|
esp_err_t disable(endpoint_t *endpoint)
|
||||||
{
|
{
|
||||||
VerifyOrReturnError(endpoint, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Endpoint cannot be NULL"));
|
VerifyOrReturnError(endpoint, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Endpoint cannot be NULL"));
|
||||||
_endpoint_t *current_endpoint = (_endpoint_t *)endpoint;
|
_endpoint_t *current_endpoint = (_endpoint_t *)endpoint;
|
||||||
current_endpoint->enabled = false;
|
current_endpoint->enabled = false;
|
||||||
|
{
|
||||||
|
esp_matter::lock::ScopedChipStackLock lock(portMAX_DELAY);
|
||||||
|
report_parts_list_change_internal(endpoint);
|
||||||
|
cluster_t *cluster = cluster::get_first(endpoint);
|
||||||
|
while (cluster) {
|
||||||
|
/* kClusterShutdown type shutdown callback */
|
||||||
|
cluster::shutdown_callback_t shutdown_callback = cluster::get_shutdown_callback(cluster);
|
||||||
|
if (shutdown_callback) {
|
||||||
|
shutdown_callback(endpoint::get_id(endpoint), chip::app::ClusterShutdownType::kClusterShutdown);
|
||||||
|
}
|
||||||
|
cluster = cluster::get_next(cluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,43 +266,62 @@ static esp_err_t init_identification(endpoint_t *endpoint)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void invoke_init_callbacks_internal(endpoint_t *endpoint)
|
||||||
|
{
|
||||||
|
cluster_t *cluster = cluster::get_first(endpoint);
|
||||||
|
while (cluster) {
|
||||||
|
/* Delegate server init callback */
|
||||||
|
cluster::delegate_init_callback_t delegate_init_callback = cluster::get_delegate_init_callback(cluster);
|
||||||
|
if (delegate_init_callback) {
|
||||||
|
delegate_init_callback(cluster::get_delegate_impl(cluster), endpoint::get_id(endpoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add bounds callback */
|
||||||
|
cluster::add_bounds_callback_t add_bounds_callback = cluster::get_add_bounds_callback(cluster);
|
||||||
|
if (add_bounds_callback) {
|
||||||
|
add_bounds_callback(cluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Plugin server init callback */
|
||||||
|
cluster::plugin_server_init_callback_t plugin_server_init_callback =
|
||||||
|
cluster::get_plugin_server_init_callback(cluster);
|
||||||
|
if (plugin_server_init_callback) {
|
||||||
|
plugin_server_init_callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialization callback */
|
||||||
|
uint8_t flags = cluster::get_flags(cluster);
|
||||||
|
cluster::initialization_callback_t init_callback = cluster::get_init_callback(cluster);
|
||||||
|
if (init_callback) {
|
||||||
|
init_callback(endpoint::get_id(endpoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init function */
|
||||||
|
if ((flags & CLUSTER_FLAG_SERVER) && (flags & CLUSTER_FLAG_INIT_FUNCTION)) {
|
||||||
|
cluster::function_cluster_init_t init_function =
|
||||||
|
(cluster::function_cluster_init_t)cluster::get_function(cluster, CLUSTER_FLAG_INIT_FUNCTION);
|
||||||
|
if (init_function) {
|
||||||
|
init_function(endpoint::get_id(endpoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cluster = cluster::get_next(cluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t enable(endpoint_t *endpoint)
|
esp_err_t enable(endpoint_t *endpoint)
|
||||||
{
|
{
|
||||||
VerifyOrReturnError(endpoint, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Endpoint cannot be NULL"));
|
VerifyOrReturnError(endpoint, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Endpoint cannot be NULL"));
|
||||||
_endpoint_t *current_endpoint = (_endpoint_t *)endpoint;
|
_endpoint_t *current_endpoint = (_endpoint_t *)endpoint;
|
||||||
current_endpoint->enabled = true;
|
current_endpoint->enabled = true;
|
||||||
init_identification(endpoint);
|
init_identification(endpoint);
|
||||||
esp_matter::cluster::delegate_init_callback_common(endpoint);
|
{
|
||||||
chip::DeviceLayer::SystemLayer().ScheduleLambda([endpoint] {
|
// Use the lock instead of schedule lambda to ensure the callbacks are invoked before esp_matter::start() returns.
|
||||||
cluster_t *cluster = cluster::get_first(endpoint);
|
esp_matter::lock::ScopedChipStackLock lock(portMAX_DELAY);
|
||||||
while (cluster) {
|
invoke_init_callbacks_internal(endpoint);
|
||||||
/* Add bounds callback */
|
// Mark the endpoint as dirty so that the data model provider will report the attribute changes.
|
||||||
cluster::add_bounds_callback_t add_bounds_callback = cluster::get_add_bounds_callback(cluster);
|
MatterReportingAttributeChangeCallback(endpoint::get_id(endpoint));
|
||||||
if (add_bounds_callback) {
|
report_parts_list_change_internal(endpoint);
|
||||||
add_bounds_callback(cluster);
|
}
|
||||||
}
|
|
||||||
/* Plugin server init callback */
|
|
||||||
cluster::plugin_server_init_callback_t plugin_server_init_callback =
|
|
||||||
cluster::get_plugin_server_init_callback(cluster);
|
|
||||||
if (plugin_server_init_callback) {
|
|
||||||
plugin_server_init_callback();
|
|
||||||
}
|
|
||||||
/* Initialization callback */
|
|
||||||
uint8_t flags = cluster::get_flags(cluster);
|
|
||||||
cluster::initialization_callback_t init_callback = cluster::get_init_callback(cluster);
|
|
||||||
if (init_callback) {
|
|
||||||
init_callback(endpoint::get_id(endpoint));
|
|
||||||
}
|
|
||||||
if ((flags & CLUSTER_FLAG_SERVER) && (flags & CLUSTER_FLAG_INIT_FUNCTION)) {
|
|
||||||
cluster::function_cluster_init_t init_function =
|
|
||||||
(cluster::function_cluster_init_t)cluster::get_function(cluster, CLUSTER_FLAG_INIT_FUNCTION);
|
|
||||||
if (init_function) {
|
|
||||||
init_function(endpoint::get_id(endpoint));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cluster = cluster::get_next(cluster);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1726,6 +1770,25 @@ esp_err_t destroy(node_t *node, endpoint_t *endpoint)
|
|||||||
}
|
}
|
||||||
VerifyOrReturnError(current_endpoint != NULL, ESP_FAIL, ESP_LOGE(TAG, "Could not find the endpoint to delete"));
|
VerifyOrReturnError(current_endpoint != NULL, ESP_FAIL, ESP_LOGE(TAG, "Could not find the endpoint to delete"));
|
||||||
|
|
||||||
|
{
|
||||||
|
esp_matter::lock::ScopedChipStackLock lock(portMAX_DELAY);
|
||||||
|
cluster_t *cluster = cluster::get_first(endpoint);
|
||||||
|
while (cluster) {
|
||||||
|
/* TODO: kPermanentRemove type shutdown callback is not implemented yet in upstream code */
|
||||||
|
|
||||||
|
/* Shutdown function */
|
||||||
|
uint8_t flags = cluster::get_flags(cluster);
|
||||||
|
if ((flags & CLUSTER_FLAG_SERVER) && (flags & CLUSTER_FLAG_SHUTDOWN_FUNCTION)) {
|
||||||
|
cluster::function_cluster_shutdown_t shutdown_function =
|
||||||
|
(cluster::function_cluster_shutdown_t)cluster::get_function(cluster, CLUSTER_FLAG_SHUTDOWN_FUNCTION);
|
||||||
|
if (shutdown_function) {
|
||||||
|
shutdown_function(endpoint::get_id(endpoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cluster = cluster::get_next(cluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse and delete all clusters */
|
/* Parse and delete all clusters */
|
||||||
_cluster_t *cluster = current_endpoint->cluster_list;
|
_cluster_t *cluster = current_endpoint->cluster_list;
|
||||||
while (cluster) {
|
while (cluster) {
|
||||||
|
|||||||
@@ -40,15 +40,6 @@ esp_err_t enable_all();
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace cluster {
|
|
||||||
|
|
||||||
/** Common cluster delegate init callback
|
|
||||||
*
|
|
||||||
* This is the common delegate init callback which calls the delegate init callbacks in the clusters.
|
|
||||||
*/
|
|
||||||
void delegate_init_callback_common(endpoint_t *endpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace attribute {
|
namespace attribute {
|
||||||
|
|
||||||
/** Get the attribute value from the esp-matter storage
|
/** Get the attribute value from the esp-matter storage
|
||||||
|
|||||||
@@ -646,9 +646,13 @@ CHIP_ERROR provider::Attributes(const ConcreteClusterPath &path, ReadOnlyBufferB
|
|||||||
|
|
||||||
void provider::Temporary_ReportAttributeChanged(const AttributePathParams &path)
|
void provider::Temporary_ReportAttributeChanged(const AttributePathParams &path)
|
||||||
{
|
{
|
||||||
cluster_t *cluster = cluster::get(path.mEndpointId, path.mClusterId);
|
VerifyOrReturn(!path.HasWildcardEndpointId());
|
||||||
VerifyOrReturn(cluster != nullptr);
|
// If the cluster is not wildcard, increase the data version
|
||||||
VerifyOrReturn(cluster::increase_data_version(cluster) == ESP_OK);
|
if (!path.HasWildcardClusterId()) {
|
||||||
|
cluster_t *cluster = cluster::get(path.mEndpointId, path.mClusterId);
|
||||||
|
VerifyOrReturn(cluster != nullptr);
|
||||||
|
VerifyOrReturn(cluster::increase_data_version(cluster) == ESP_OK);
|
||||||
|
}
|
||||||
mContext->dataModelChangeListener.MarkDirty(path);
|
mContext->dataModelChangeListener.MarkDirty(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user