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:
@@ -121,20 +121,6 @@ cluster_t * ABORT_CLUSTER_CREATE(cluster_t *cluster)
|
||||
}
|
||||
} // 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)
|
||||
{
|
||||
/* 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 {
|
||||
|
||||
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)
|
||||
{
|
||||
VerifyOrReturnError(endpoint, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Endpoint cannot be NULL"));
|
||||
_endpoint_t *current_endpoint = (_endpoint_t *)endpoint;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -241,43 +266,62 @@ static esp_err_t init_identification(endpoint_t *endpoint)
|
||||
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)
|
||||
{
|
||||
VerifyOrReturnError(endpoint, ESP_ERR_INVALID_ARG, ESP_LOGE(TAG, "Endpoint cannot be NULL"));
|
||||
_endpoint_t *current_endpoint = (_endpoint_t *)endpoint;
|
||||
current_endpoint->enabled = true;
|
||||
init_identification(endpoint);
|
||||
esp_matter::cluster::delegate_init_callback_common(endpoint);
|
||||
chip::DeviceLayer::SystemLayer().ScheduleLambda([endpoint] {
|
||||
cluster_t *cluster = cluster::get_first(endpoint);
|
||||
while (cluster) {
|
||||
/* 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));
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
{
|
||||
// Use the lock instead of schedule lambda to ensure the callbacks are invoked before esp_matter::start() returns.
|
||||
esp_matter::lock::ScopedChipStackLock lock(portMAX_DELAY);
|
||||
invoke_init_callbacks_internal(endpoint);
|
||||
// Mark the endpoint as dirty so that the data model provider will report the attribute changes.
|
||||
MatterReportingAttributeChangeCallback(endpoint::get_id(endpoint));
|
||||
report_parts_list_change_internal(endpoint);
|
||||
}
|
||||
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"));
|
||||
|
||||
{
|
||||
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 */
|
||||
_cluster_t *cluster = current_endpoint->cluster_list;
|
||||
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 {
|
||||
|
||||
/** 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)
|
||||
{
|
||||
cluster_t *cluster = cluster::get(path.mEndpointId, path.mClusterId);
|
||||
VerifyOrReturn(cluster != nullptr);
|
||||
VerifyOrReturn(cluster::increase_data_version(cluster) == ESP_OK);
|
||||
VerifyOrReturn(!path.HasWildcardEndpointId());
|
||||
// If the cluster is not wildcard, increase the data version
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user