From 89fe5168f7f4af3a16adbd3270f89c53125092b0 Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Fri, 24 Oct 2025 09:35:57 +0800 Subject: [PATCH] submodule: Update connectedhomeip submodule to v1.5 sve tag --- .gitlab-ci.yml | 3 +- README.md | 2 +- components/esp_matter/CMakeLists.txt | 1 + .../data_model/esp_matter_cluster.cpp | 26 +- .../data_model/esp_matter_command.cpp | 235 ++-------------- .../private/esp_matter_cluster_revisions.h | 2 +- .../clusters/access_control_integration.cpp | 52 ++++ ...dministrator_commissioning_integration.cpp | 2 +- .../basic_information_integration.cpp | 50 ++++ .../clusters/binding_integration.cpp | 57 ++++ .../clusters/boolean_state_integration.cpp | 57 ++++ .../clusters/diagnostic_logs_integration.cpp | 49 ++++ ...hernet_network_diagnostics_integration.cpp | 93 +++++++ .../clusters/fixed_label_integration.cpp | 55 ++++ .../general_commissioning_integration.cpp | 49 ++++ .../general_diagnostics_integration.cpp | 45 ++-- .../group_key_management_integration.cpp | 51 ++++ .../operational_credentials_integration.cpp | 58 ++++ .../clusters/ota_provider_integration.cpp | 5 +- .../push_av_stream_transport_integration.cpp | 9 +- .../software_diagnostics_integration.cpp | 27 +- .../time_format_localization_integration.cpp | 96 +++++++ .../wifi_network_diagnostic_integration.cpp | 13 +- .../esp_matter_data_model_provider.cpp | 122 +++------ .../esp_matter_data_model_provider.h | 5 +- .../esp_matter_ember_stubs.cpp | 255 ------------------ ...sp_matter_plugin_server_init_callbacks.cpp | 1 - components/esp_matter/esp_matter_client.cpp | 11 +- components/esp_matter/esp_matter_client.h | 34 +-- .../utils/cluster_select/Kconfig.in | 8 + .../utils/cluster_select/cluster_dir.cmake | 6 + .../zap_common/app/ClusterCallbacks.h | 3 + .../app/PluginApplicationCallbacks.h | 1 + .../zap_common/zap-generated/access.h | 21 +- connectedhomeip/connectedhomeip | 2 +- .../platform/ESP32_custom/BUILD.gn | 1 - .../platform/ESP32_custom/LwIPCoreLock.cpp | 1 - examples/common/external_platform/BUILD.gn | 1 - examples/zap_light/main/CMakeLists.txt | 2 - tools/ci/certification_test_commands.json | 4 +- tools/ci/pytest_cert_helper.py | 17 +- 41 files changed, 870 insertions(+), 662 deletions(-) create mode 100644 components/esp_matter/data_model_provider/clusters/access_control_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/basic_information_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/binding_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/boolean_state_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/diagnostic_logs_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/ethernet_network_diagnostics_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/fixed_label_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/general_commissioning_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/group_key_management_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/operational_credentials_integration.cpp create mode 100644 components/esp_matter/data_model_provider/clusters/time_format_localization_integration.cpp delete mode 120000 examples/common/blemesh_platform/platform/ESP32_custom/LwIPCoreLock.cpp diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4351608ef..c6866b90c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,7 +28,7 @@ variables: IDF_CHECKOUT_REF: "v5.4.1" # This variable represents the short hash of the connectedhomeip submodule. # Note: Do change this short hash on submodule update MRs. - CHIP_SHORT_HASH: "bdc38cd772" + CHIP_SHORT_HASH: "f902839abf" DOCKER_IMAGE_NAME: "espressif/chip-idf" .add_gitlab_ssh_key: &add_gitlab_ssh_key | @@ -278,7 +278,6 @@ build_image: - *add_gitlab_ssh_key - *get_build_caches - *setup_idf - - pip install 'idf-component-manager~=2.1.2' - cd ${ESP_MATTER_PATH} - mkdir -p ${REPOS_PATH} - *update_build_caches diff --git a/README.md b/README.md index b12e3c77a..121ade6a0 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ section in the ESP-Matter Programming Guide. ## Supported ESP-IDF and connectedhomeip versions -- This SDK currently works with commit [bdc38cd772] (https://github.com/project-chip/connectedhomeip/tree/bdc38cd772) of connectedhomeip. +- This SDK currently works with commit [f902839abf] (https://github.com/project-chip/connectedhomeip/tree/f902839abf) of connectedhomeip. - For Matter projects development with this SDK, it is recommended to utilize ESP-IDF [v5.4.1](https://github.com/espressif/esp-idf/tree/v5.4.1). - For ESP32C5 and ESP32C61, it is recommended to utilize ESP-IDF [v5.5.1](https://github.com/espressif/esp-idf/tree/v5.5.1). diff --git a/components/esp_matter/CMakeLists.txt b/components/esp_matter/CMakeLists.txt index 02a36278c..ad79e53c2 100644 --- a/components/esp_matter/CMakeLists.txt +++ b/components/esp_matter/CMakeLists.txt @@ -19,6 +19,7 @@ set(PRIV_INCLUDE_DIRS_LIST ) if (CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) list(APPEND SRC_DIRS_LIST "${MATTER_SDK_PATH}/src/app/server" "${MATTER_SDK_PATH}/src/app/reporting" + "${MATTER_SDK_PATH}/src/app/persistence" "${MATTER_SDK_PATH}/src/app/server-cluster") if (CONFIG_ESP_MATTER_ENABLE_DATA_MODEL) include("utils/cluster_select/cluster_dir.cmake") diff --git a/components/esp_matter/data_model/esp_matter_cluster.cpp b/components/esp_matter/data_model/esp_matter_cluster.cpp index 11fe1c9b5..f0a51722b 100644 --- a/components/esp_matter/data_model/esp_matter_cluster.cpp +++ b/components/esp_matter/data_model/esp_matter_cluster.cpp @@ -272,6 +272,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Attributes not managed internally */ global::attribute::create_cluster_revision(cluster, cluster_revision); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterAccessControlClusterServerInitCallback, + ESPMatterAccessControlClusterServerShutdownCallback); } event::create_access_control_entry_changed(cluster); @@ -320,6 +322,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } else { ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); } + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterBasicInformationClusterServerInitCallback, + ESPMatterBasicInformationClusterServerShutdownCallback); } event::create_start_up(cluster); @@ -349,11 +353,9 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Attributes not managed internally */ global::attribute::create_cluster_revision(cluster, cluster_revision); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterBindingClusterServerInitCallback, + ESPMatterBindingClusterServerShutdownCallback); } - - /* Extra initialization */ - client::binding_init(); - return cluster; } } /* binding */ @@ -474,6 +476,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) command::create_set_regulatory_config_response(cluster); command::create_commissioning_complete(cluster); command::create_commissioning_complete_response(cluster); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterGeneralCommissioningClusterServerInitCallback, + ESPMatterGeneralCommissioningClusterServerShutdownCallback); } return cluster; @@ -662,6 +666,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) command::create_set_vid_verification_statement(cluster); command::create_sign_vid_verification_request(cluster); command::create_sign_vid_verification_response(cluster); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterOperationalCredentialsClusterServerInitCallback, + ESPMatterOperationalCredentialsClusterServerShutdownCallback); } return cluster; @@ -697,6 +703,8 @@ cluster_t *create(endpoint_t *endpoint, uint8_t flags) command::create_key_set_read_all_indices(cluster); command::create_key_set_read_response(cluster); command::create_key_set_read_all_indices_response(cluster); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterGroupKeyManagementClusterServerInitCallback, + ESPMatterGroupKeyManagementClusterServerShutdownCallback); } return cluster; @@ -796,6 +804,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Attributes not managed internally */ global::attribute::create_cluster_revision(cluster, cluster_revision); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterEthernetNetworkDiagnosticsClusterServerInitCallback, + ESPMatterEthernetNetworkDiagnosticsClusterServerShutdownCallback); } return cluster; @@ -1020,6 +1030,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Attributes not managed internally */ global::attribute::create_cluster_revision(cluster, cluster_revision); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterFixedLabelClusterServerInitCallback, + ESPMatterFixedLabelClusterServerShutdownCallback); } return cluster; @@ -2312,6 +2324,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } else { ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); } + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterBooleanStateClusterServerInitCallback, + ESPMatterBooleanStateClusterServerShutdownCallback); } if (flags & CLUSTER_FLAG_CLIENT) { @@ -2419,6 +2433,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } else { ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); } + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterTimeFormatLocalizationClusterServerInitCallback, + ESPMatterTimeFormatLocalizationClusterServerShutdownCallback); } return cluster; @@ -2670,6 +2686,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Attributes not managed internally */ global::attribute::create_cluster_revision(cluster, cluster_revision); + cluster::set_init_and_shutdown_callbacks(cluster, ESPMatterDiagnosticLogsClusterServerInitCallback, + ESPMatterDiagnosticLogsClusterServerShutdownCallback); } if (flags & CLUSTER_FLAG_CLIENT) { diff --git a/components/esp_matter/data_model/esp_matter_command.cpp b/components/esp_matter/data_model/esp_matter_command.cpp index 2d76ba406..9bf147231 100644 --- a/components/esp_matter/data_model/esp_matter_command.cpp +++ b/components/esp_matter/data_model/esp_matter_command.cpp @@ -70,186 +70,6 @@ void dispatch_single_cluster_command(const ConcreteCommandPath &command_path, TL } /* command */ } /* esp_matter */ -static esp_err_t esp_matter_command_callback_key_set_write(const ConcreteCommandPath &command_path, TLVReader &tlv_data, - void *opaque_ptr) -{ - chip::app::Clusters::GroupKeyManagement::Commands::KeySetWrite::DecodableType command_data; - chip::app::CommandHandler *command_obj = (chip::app::CommandHandler *)opaque_ptr; - CHIP_ERROR error = command_data.Decode(tlv_data, command_obj->GetAccessingFabricIndex()); - - if (error == CHIP_NO_ERROR) { - emberAfGroupKeyManagementClusterKeySetWriteCallback((CommandHandler *)opaque_ptr, command_path, command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_key_set_read(const ConcreteCommandPath &command_path, TLVReader &tlv_data, - void *opaque_ptr) -{ - chip::app::Clusters::GroupKeyManagement::Commands::KeySetRead::DecodableType command_data; - chip::app::CommandHandler *command_obj = (chip::app::CommandHandler *)opaque_ptr; - CHIP_ERROR error = command_data.Decode(tlv_data, command_obj->GetAccessingFabricIndex()); - - if (error == CHIP_NO_ERROR) { - emberAfGroupKeyManagementClusterKeySetReadCallback((CommandHandler *)opaque_ptr, command_path, command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_key_set_remove(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::GroupKeyManagement::Commands::KeySetRemove::DecodableType command_data; - chip::app::CommandHandler *command_obj = (chip::app::CommandHandler *)opaque_ptr; - CHIP_ERROR error = command_data.Decode(tlv_data, command_obj->GetAccessingFabricIndex()); - - if (error == CHIP_NO_ERROR) { - emberAfGroupKeyManagementClusterKeySetRemoveCallback((CommandHandler *)opaque_ptr, command_path, command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_key_set_read_all_indices(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::GroupKeyManagement::Commands::KeySetReadAllIndices::DecodableType command_data; - chip::app::CommandHandler *command_obj = (chip::app::CommandHandler *)opaque_ptr; - CHIP_ERROR error = command_data.Decode(tlv_data, command_obj->GetAccessingFabricIndex()); - - if (error == CHIP_NO_ERROR) { - emberAfGroupKeyManagementClusterKeySetReadAllIndicesCallback((CommandHandler *)opaque_ptr, command_path, - command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_attestation_request(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::AttestationRequest::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterAttestationRequestCallback((CommandHandler *)opaque_ptr, command_path, - command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_certificate_chain_request(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::CertificateChainRequest::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterCertificateChainRequestCallback((CommandHandler *)opaque_ptr, command_path, - command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_csr_request(const ConcreteCommandPath &command_path, TLVReader &tlv_data, - void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::CSRRequest::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterCSRRequestCallback((CommandHandler *)opaque_ptr, command_path, - command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_add_noc(const ConcreteCommandPath &command_path, TLVReader &tlv_data, - void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::AddNOC::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterAddNOCCallback((CommandHandler *)opaque_ptr, command_path, command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_update_noc(const ConcreteCommandPath &command_path, TLVReader &tlv_data, - void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::UpdateNOC::DecodableType command_data; - chip::app::CommandHandler *command_obj = (chip::app::CommandHandler *)opaque_ptr; - CHIP_ERROR error = command_data.Decode(tlv_data, command_obj->GetAccessingFabricIndex()); - - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterUpdateNOCCallback((CommandHandler *)opaque_ptr, command_path, command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_update_fabric_label(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::UpdateFabricLabel::DecodableType command_data; - chip::app::CommandHandler *command_obj = (chip::app::CommandHandler *)opaque_ptr; - CHIP_ERROR error = command_data.Decode(tlv_data, command_obj->GetAccessingFabricIndex()); - - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterUpdateFabricLabelCallback((CommandHandler *)opaque_ptr, command_path, - command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_remove_fabric(const ConcreteCommandPath &command_path, TLVReader &tlv_data, - void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::RemoveFabric::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterRemoveFabricCallback((CommandHandler *)opaque_ptr, command_path, - command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_add_trusted_root_certificate(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::AddTrustedRootCertificate::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterAddTrustedRootCertificateCallback((CommandHandler *)opaque_ptr, - command_path, command_data); - } - return ESP_OK; -} - - -static esp_err_t esp_matter_command_callback_set_vid_verification_statement(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::SetVIDVerificationStatement::DecodableType command_data; - chip::app::CommandHandler *command_obj = (chip::app::CommandHandler *)opaque_ptr; - CHIP_ERROR error = command_data.Decode(tlv_data, command_obj->GetAccessingFabricIndex()); - - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterSetVIDVerificationStatementCallback((CommandHandler *)opaque_ptr, - command_path, command_data); - } - return ESP_OK; -} - - -static esp_err_t esp_matter_command_callback_sign_vid_verification_request(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::OperationalCredentials::Commands::SignVIDVerificationRequest::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfOperationalCredentialsClusterSignVIDVerificationRequestCallback((CommandHandler *)opaque_ptr, - command_path, command_data); - } - return ESP_OK; -} - - static esp_err_t esp_matter_command_callback_announce_ota_provider(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr) { @@ -1108,29 +928,6 @@ static esp_err_t esp_matter_command_callback_thread_reset_counts(const ConcreteC return ESP_OK; } -static esp_err_t esp_matter_command_callback_ethernet_reset_counts(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::EthernetNetworkDiagnostics::Commands::ResetCounts::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfEthernetNetworkDiagnosticsClusterResetCountsCallback((CommandHandler *)opaque_ptr, command_path, - command_data); - } - return ESP_OK; -} - -static esp_err_t esp_matter_command_callback_retrieve_logs_request(const ConcreteCommandPath &command_path, - TLVReader &tlv_data, void *opaque_ptr) -{ - chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsRequest::DecodableType command_data; - CHIP_ERROR error = Decode(tlv_data, command_data); - if (error == CHIP_NO_ERROR) { - emberAfDiagnosticLogsClusterRetrieveLogsRequestCallback((CommandHandler *)opaque_ptr, command_path, command_data); - } - return ESP_OK; -} - static esp_err_t esp_matter_command_callback_up_or_open(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr) { @@ -1632,7 +1429,7 @@ namespace command { command_t *create_reset_counts(cluster_t *cluster) { return esp_matter::command::create(cluster, EthernetNetworkDiagnostics::Commands::ResetCounts::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_ethernet_reset_counts); + NULL); } } /* command */ @@ -1644,7 +1441,7 @@ namespace command { command_t *create_retrieve_logs_request(cluster_t *cluster) { return esp_matter::command::create(cluster, DiagnosticLogs::Commands::RetrieveLogsRequest::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_retrieve_logs_request); + NULL); } command_t *create_retrieve_logs_response(cluster_t *cluster) @@ -1696,25 +1493,25 @@ namespace command { command_t *create_key_set_write(cluster_t *cluster) { return esp_matter::command::create(cluster, GroupKeyManagement::Commands::KeySetWrite::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_key_set_write); + NULL); } command_t *create_key_set_read(cluster_t *cluster) { return esp_matter::command::create(cluster, GroupKeyManagement::Commands::KeySetRead::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_key_set_read); + NULL); } command_t *create_key_set_remove(cluster_t *cluster) { return esp_matter::command::create(cluster, GroupKeyManagement::Commands::KeySetRemove::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_key_set_remove); + NULL); } command_t *create_key_set_read_all_indices(cluster_t *cluster) { return esp_matter::command::create(cluster, GroupKeyManagement::Commands::KeySetReadAllIndices::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_key_set_read_all_indices); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_key_set_read_response(cluster_t *cluster) @@ -1876,49 +1673,49 @@ namespace command { command_t *create_attestation_request(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::AttestationRequest::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_attestation_request); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_certificate_chain_request(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::CertificateChainRequest::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_certificate_chain_request); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_csr_request(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::CSRRequest::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_csr_request); + NULL); } command_t *create_add_noc(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::AddNOC::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_add_noc); + NULL); } command_t *create_update_noc(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::UpdateNOC::Id, COMMAND_FLAG_ACCEPTED, - esp_matter_command_callback_update_noc); + NULL); } command_t *create_update_fabric_label(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::UpdateFabricLabel::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_update_fabric_label); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_remove_fabric(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::RemoveFabric::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_remove_fabric); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_add_trusted_root_certificate(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::AddTrustedRootCertificate::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_add_trusted_root_certificate); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_attestation_response(cluster_t *cluster) @@ -1948,13 +1745,13 @@ command_t *create_noc_response(cluster_t *cluster) command_t *create_set_vid_verification_statement(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::SetVIDVerificationStatement::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_vid_verification_statement); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_sign_vid_verification_request(cluster_t *cluster) { return esp_matter::command::create(cluster, OperationalCredentials::Commands::SignVIDVerificationRequest::Id, - COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_sign_vid_verification_request); + COMMAND_FLAG_ACCEPTED, NULL); } command_t *create_sign_vid_verification_response(cluster_t *cluster) diff --git a/components/esp_matter/data_model/private/esp_matter_cluster_revisions.h b/components/esp_matter/data_model/private/esp_matter_cluster_revisions.h index d71587a83..49420e83c 100644 --- a/components/esp_matter/data_model/private/esp_matter_cluster_revisions.h +++ b/components/esp_matter/data_model/private/esp_matter_cluster_revisions.h @@ -140,7 +140,7 @@ constexpr uint16_t cluster_revision = 6; } // namespace level_control namespace color_control { -constexpr uint16_t cluster_revision = 7; +constexpr uint16_t cluster_revision = 8; } // namespace color_control namespace fan_control { diff --git a/components/esp_matter/data_model_provider/clusters/access_control_integration.cpp b/components/esp_matter/data_model_provider/clusters/access_control_integration.cpp new file mode 100644 index 000000000..b1e69c4aa --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/access_control_integration.cpp @@ -0,0 +1,52 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +LazyRegisteredServerCluster gServer; +} + +void ESPMatterAccessControlClusterServerInitCallback(EndpointId endpoint) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpoint == kRootEndpointId); + + gServer.Create(); + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gServer.Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register AccessControl - Error %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void ESPMatterAccessControlClusterServerShutdownCallback(EndpointId endpointId) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpointId == kRootEndpointId); + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServer.Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister AccessControl - Error %" CHIP_ERROR_FORMAT, err.Format()); + } + gServer.Destroy(); +} + +void MatterAccessControlPluginServerInitCallback() {} + +void MatterAccessControlPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/administrator_commissioning_integration.cpp b/components/esp_matter/data_model_provider/clusters/administrator_commissioning_integration.cpp index 8c5a6cd0d..0ca4f665d 100644 --- a/components/esp_matter/data_model_provider/clusters/administrator_commissioning_integration.cpp +++ b/components/esp_matter/data_model_provider/clusters/administrator_commissioning_integration.cpp @@ -55,7 +55,7 @@ void ESPMatterAdministratorCommissioningClusterServerShutdownCallback(EndpointId { CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServer.Cluster()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Admin Commissioning unregister error: %" CHIP_ERROR_FORMAT, err.Format()) + ChipLogError(AppServer, "Admin Commissioning unregister error: %" CHIP_ERROR_FORMAT, err.Format()); } gServer.Destroy(); } diff --git a/components/esp_matter/data_model_provider/clusters/basic_information_integration.cpp b/components/esp_matter/data_model_provider/clusters/basic_information_integration.cpp new file mode 100644 index 000000000..f3c71bbfc --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/basic_information_integration.cpp @@ -0,0 +1,50 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +ServerClusterRegistration gRegistration(BasicInformationCluster::Instance()); +} + +void ESPMatterBasicInformationClusterServerInitCallback(EndpointId endpoint) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpoint == kRootEndpointId); + + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gRegistration); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register BasicInformation - Error %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void ESPMatterBasicInformationClusterServerShutdownCallback(EndpointId endpointId) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpointId == kRootEndpointId); + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Unregister(gRegistration.serverClusterInterface); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister BasicInformation - Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void MatterBasicInformationPluginServerInitCallback() {} +void MatterBasicInformationPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/binding_integration.cpp b/components/esp_matter/data_model_provider/clusters/binding_integration.cpp new file mode 100644 index 000000000..af16164aa --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/binding_integration.cpp @@ -0,0 +1,57 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +std::unordered_map> gServers; + +} // namespace + +void ESPMatterBindingClusterServerInitCallback(EndpointId endpointId) +{ + if (gServers[endpointId].IsConstructed()) { + return; + } + + gServers[endpointId].Create(endpointId); + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Register(gServers[endpointId].Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register Binding on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, + err.Format()); + } +} + +void ESPMatterBindingClusterServerShutdownCallback(EndpointId endpointId) +{ + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Unregister(&gServers[endpointId].Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister Binding on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, + err.Format()); + } + gServers[endpointId].Destroy(); +} + +void MatterBindingPluginServerInitCallback() {} + +void MatterBindingPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/boolean_state_integration.cpp b/components/esp_matter/data_model_provider/clusters/boolean_state_integration.cpp new file mode 100644 index 000000000..ff2486090 --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/boolean_state_integration.cpp @@ -0,0 +1,57 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +std::unordered_map> gServers; + +} // namespace + +void ESPMatterBooleanStateClusterServerInitCallback(EndpointId endpointId) +{ + if (gServers[endpointId].IsConstructed()) { + return; + } + + gServers[endpointId].Create(endpointId); + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Register(gServers[endpointId].Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register BooleanState on endpoint %u - Error: %" CHIP_ERROR_FORMAT, + endpointId, err.Format()); + } +} + +void ESPMatterBooleanStateClusterServerShutdownCallback(EndpointId endpointId) +{ + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Unregister(&gServers[endpointId].Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister BooleanState on endpoint %u - Error: %" CHIP_ERROR_FORMAT, + endpointId, err.Format()); + } + gServers[endpointId].Destroy(); +} + +void MatterBooleanStatePluginServerInitCallback() {} + +void MatterBooleanStatePluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/diagnostic_logs_integration.cpp b/components/esp_matter/data_model_provider/clusters/diagnostic_logs_integration.cpp new file mode 100644 index 000000000..686791da0 --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/diagnostic_logs_integration.cpp @@ -0,0 +1,49 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +void ESPMatterDiagnosticLogsClusterServerInitCallback(EndpointId endpoint) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpoint == kRootEndpointId); + static ServerClusterRegistration sRegistration(DiagnosticLogsCluster::Instance()); + + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(sRegistration); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register DiagnosticLogs on endpoint %u - Error: %" CHIP_ERROR_FORMAT, + endpoint, err.Format()); + } +} + +void ESPMatterDiagnosticLogsClusterServerShutdownCallback(EndpointId endpointId) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpointId == kRootEndpointId); + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Unregister(&DiagnosticLogsCluster::Instance()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister DiagnosticLogs on endpoint %u - Error: %" CHIP_ERROR_FORMAT, + endpointId, err.Format()); + } +} + +void MatterDiagnosticLogsPluginServerInitCallback() {} +void MatterDiagnosticLogsPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/ethernet_network_diagnostics_integration.cpp b/components/esp_matter/data_model_provider/clusters/ethernet_network_diagnostics_integration.cpp new file mode 100644 index 000000000..3ac49141d --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/ethernet_network_diagnostics_integration.cpp @@ -0,0 +1,93 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +std::unordered_map> gServers; + +uint32_t get_feature_map(esp_matter::cluster_t *cluster) +{ + esp_matter::attribute_t *attribute = esp_matter::attribute::get(cluster, Globals::Attributes::FeatureMap::Id); + if (attribute) { + esp_matter_attr_val_t val = esp_matter_invalid(nullptr); + if (esp_matter::attribute::get_val(attribute, &val) == ESP_OK && val.type == ESP_MATTER_VAL_TYPE_BITMAP32) { + return val.val.u32; + } + } + return 0; +} + +EthernetDiagnosticsServerCluster::OptionalAttributeSet get_attribute_set(esp_matter::cluster_t *cluster) +{ + EthernetDiagnosticsServerCluster::OptionalAttributeSet ret; + if (esp_matter::attribute::get(cluster, EthernetNetworkDiagnostics::Attributes::CarrierDetect::Id)) { + ret.Set(); + } + if (esp_matter::attribute::get(cluster, EthernetNetworkDiagnostics::Attributes::FullDuplex::Id)) { + ret.Set(); + } + if (esp_matter::attribute::get(cluster, EthernetNetworkDiagnostics::Attributes::PHYRate::Id)) { + ret.Set(); + } + if (esp_matter::attribute::get(cluster, EthernetNetworkDiagnostics::Attributes::TimeSinceReset::Id)) { + ret.Set(); + } + return ret; +} + +} // namespace + +void ESPMatterEthernetNetworkDiagnosticsClusterServerInitCallback(EndpointId endpointId) +{ + if (gServers[endpointId].IsConstructed()) { + return; + } + esp_matter::cluster_t *cluster = esp_matter::cluster::get(endpointId, EthernetNetworkDiagnostics::Id); + + gServers[endpointId].Create(DeviceLayer::GetDiagnosticDataProvider(), + BitFlags(get_feature_map(cluster)), + get_attribute_set(cluster)); + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Register(gServers[endpointId].Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, + "Failed to register EthernetNetworkDiagnostics on endpoint %u - Error: %" CHIP_ERROR_FORMAT, + endpointId, err.Format()); + } +} + +void ESPMatterEthernetNetworkDiagnosticsClusterServerShutdownCallback(EndpointId endpointId) +{ + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Unregister(&gServers[endpointId].Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, + "Failed to unregister EthernetNetworkDiagnostics on endpoint %u - Error: %" CHIP_ERROR_FORMAT, + endpointId, err.Format()); + } + gServers[endpointId].Destroy(); +} + +void MatterEthernetNetworkDiagnosticsPluginServerInitCallback() {} + +void MatterEthernetNetworkDiagnosticsPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/fixed_label_integration.cpp b/components/esp_matter/data_model_provider/clusters/fixed_label_integration.cpp new file mode 100644 index 000000000..31a17b946 --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/fixed_label_integration.cpp @@ -0,0 +1,55 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +std::unordered_map> gServers; + +} // namespace + +void ESPMatterFixedLabelClusterServerInitCallback(EndpointId endpointId) +{ + if (gServers[endpointId].IsConstructed()) { + return; + } + + gServers[endpointId].Create(endpointId); + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Register(gServers[endpointId].Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register FixedLabel on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, + err.Format()); + } +} + +void ESPMatterFixedLabelClusterServerShutdownCallback(EndpointId endpointId) +{ + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Unregister(&gServers[endpointId].Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister FixedLabel on endpoint %u - Error: %" CHIP_ERROR_FORMAT, + endpointId, err.Format()); + } + gServers[endpointId].Destroy(); +} + +void MatterFixedLabelPluginServerInitCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/general_commissioning_integration.cpp b/components/esp_matter/data_model_provider/clusters/general_commissioning_integration.cpp new file mode 100644 index 000000000..d297de481 --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/general_commissioning_integration.cpp @@ -0,0 +1,49 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +ServerClusterRegistration gRegistration(GeneralCommissioningCluster::Instance()); +} + +void ESPMatterGeneralCommissioningClusterServerInitCallback(EndpointId endpointId) +{ + if (endpointId != kRootEndpointId) { + return; + } + + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gRegistration); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register GeneralCommissioning - Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void ESPMatterGeneralCommissioningClusterServerShutdownCallback(EndpointId endpointId) +{ + CHIP_ERROR err = + esp_matter::data_model::provider::get_instance().registry().Unregister(gRegistration.serverClusterInterface); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister GeneralCommissioning - Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void MatterGeneralCommissioningPluginServerInitCallback() {} +void MatterGeneralCommissioningPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/general_diagnostics_integration.cpp b/components/esp_matter/data_model_provider/clusters/general_diagnostics_integration.cpp index 898ef6b36..079a594d7 100644 --- a/components/esp_matter/data_model_provider/clusters/general_diagnostics_integration.cpp +++ b/components/esp_matter/data_model_provider/clusters/general_diagnostics_integration.cpp @@ -72,17 +72,22 @@ bool IsClusterEnabled(EndpointId endpointId, ClusterId clusterId) void ESPMatterGeneralDiagnosticsClusterServerInitCallback(EndpointId endpointId) { VerifyOrDie(endpointId == kRootEndpointId); - GeneralDiagnosticsEnabledAttributes enabledAttributes{ - .enableTotalOperationalHours = - IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::TotalOperationalHours::Id), - .enableBootReason = IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::BootReason::Id), - .enableActiveHardwareFaults = - IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::ActiveHardwareFaults::Id), - .enableActiveRadioFaults = - IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::ActiveRadioFaults::Id), - .enableActiveNetworkFaults = - IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::ActiveNetworkFaults::Id), - }; + GeneralDiagnosticsCluster::OptionalAttributeSet attrSet; + if (IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::TotalOperationalHours::Id)) { + attrSet.Set(); + } + if (IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::BootReason::Id)) { + attrSet.Set(); + } + if (IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::ActiveHardwareFaults::Id)) { + attrSet.Set(); + } + if (IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::ActiveRadioFaults::Id)) { + attrSet.Set(); + } + if (IsAttributeEnabled(endpointId, GeneralDiagnostics::Attributes::ActiveNetworkFaults::Id)) { + attrSet.Set(); + } CHIP_ERROR err = CHIP_NO_ERROR; if (IsCommandEnabled(endpointId, GeneralDiagnostics::Commands::PayloadTestRequest::Id, COMMAND_FLAG_ACCEPTED) || @@ -97,16 +102,15 @@ void ESPMatterGeneralDiagnosticsClusterServerInitCallback(EndpointId endpointId) IsCommandEnabled(endpointId, GeneralDiagnostics::Commands::PayloadTestRequest::Id, COMMAND_FLAG_ACCEPTED), }; - gServer.fullConfigurableServer.Create(enabledAttributes, functionsConfig); + gServer.fullConfigurableServer.Create(attrSet, functionsConfig); err = esp_matter::data_model::provider::get_instance().registry().Register( gServer.fullConfigurableServer.Registration()); } else { - gServer.server.Create(enabledAttributes); + gServer.server.Create(attrSet); err = esp_matter::data_model::provider::get_instance().registry().Register(gServer.server.Registration()); } if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to register GeneralDiagnostics on endpoint %u: %" CHIP_ERROR_FORMAT, endpointId, - err.Format()); + ChipLogError(AppServer, "Failed to register GeneralDiagnostics - Error: %" CHIP_ERROR_FORMAT, err.Format()); } } @@ -123,18 +127,13 @@ void ESPMatterGeneralDiagnosticsClusterServerShutdownCallback(EndpointId endpoin gServer.server.Destroy(); } if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to unregister GeneralDiagnostics on endpoint %u: %" CHIP_ERROR_FORMAT, - endpointId, err.Format()); + ChipLogError(AppServer, "Failed to unregister GeneralDiagnostics - Error: %" CHIP_ERROR_FORMAT, err.Format()); } } -void MatterGeneralDiagnosticsPluginServerInitCallback() -{ -} +void MatterGeneralDiagnosticsPluginServerInitCallback() {} -void MatterGeneralDiagnosticsPluginServerShutdownCallback() -{ -} +void MatterGeneralDiagnosticsPluginServerShutdownCallback() {} namespace chip::app::Clusters::GeneralDiagnostics { void GlobalNotifyDeviceReboot(GeneralDiagnostics::BootReasonEnum bootReason) diff --git a/components/esp_matter/data_model_provider/clusters/group_key_management_integration.cpp b/components/esp_matter/data_model_provider/clusters/group_key_management_integration.cpp new file mode 100644 index 000000000..c309f6730 --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/group_key_management_integration.cpp @@ -0,0 +1,51 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +LazyRegisteredServerCluster gServer; +} + +void ESPMatterGroupKeyManagementClusterServerInitCallback(EndpointId endpoint) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpoint == kRootEndpointId); + + gServer.Create(); + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gServer.Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register GroupKeyManagement - Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void ESPMatterGroupKeyManagementClusterServerShutdownCallback(EndpointId endpointId) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpointId == kRootEndpointId); + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServer.Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister GroupKeyManagement - Error: %" CHIP_ERROR_FORMAT, err.Format()); + } + gServer.Destroy(); +} + +void MatterGroupKeyManagementPluginServerInitCallback() {} +void MatterGroupKeyManagementPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/operational_credentials_integration.cpp b/components/esp_matter/data_model_provider/clusters/operational_credentials_integration.cpp new file mode 100644 index 000000000..a3600d913 --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/operational_credentials_integration.cpp @@ -0,0 +1,58 @@ + +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +LazyRegisteredServerCluster gServer; +} + +void ESPMatterOperationalCredentialsClusterServerInitCallback(EndpointId endpoint) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpoint == kRootEndpointId); + OperationalCredentialsCluster::Context context = {.fabricTable = Server::GetInstance().GetFabricTable(), + .failSafeContext = Server::GetInstance().GetFailSafeContext(), + .sessionManager = Server::GetInstance().GetSecureSessionManager(), + .dnssdServer = app::DnssdServer::Instance(), + .commissioningWindowManager = + Server::GetInstance().GetCommissioningWindowManager()}; + gServer.Create(endpoint, context); + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gServer.Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register OperationalCredentials - Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void ESPMatterOperationalCredentialsClusterServerShutdownCallback(EndpointId endpointId) +{ + // We implement the cluster as a singleton on the root endpoint. + VerifyOrReturn(endpointId == kRootEndpointId); + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServer.Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to unregister OperationalCredentials - Error: %" CHIP_ERROR_FORMAT, + err.Format()); + } + gServer.Destroy(); +} + +void MatterOperationalCredentialsPluginServerInitCallback() {} +void MatterOperationalCredentialsPluginServerShutdownCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/ota_provider_integration.cpp b/components/esp_matter/data_model_provider/clusters/ota_provider_integration.cpp index 2ed114027..efc16512d 100644 --- a/components/esp_matter/data_model_provider/clusters/ota_provider_integration.cpp +++ b/components/esp_matter/data_model_provider/clusters/ota_provider_integration.cpp @@ -35,7 +35,8 @@ void ESPMatterOtaSoftwareUpdateProviderClusterServerInitCallback(EndpointId endp CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gServers[endpointId].Registration()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to register OTA on endpoint %u: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); + ChipLogError(AppServer, "Failed to register OTA on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, + err.Format()); } } @@ -44,7 +45,7 @@ void ESPMatterOtaSoftwareUpdateProviderClusterServerShutdownCallback(EndpointId CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServers[endpointId].Cluster()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to unregister OTA on endpoint %u: %" CHIP_ERROR_FORMAT, endpointId, + ChipLogError(AppServer, "Failed to unregister OTA on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); } gServers[endpointId].Destroy(); diff --git a/components/esp_matter/data_model_provider/clusters/push_av_stream_transport_integration.cpp b/components/esp_matter/data_model_provider/clusters/push_av_stream_transport_integration.cpp index dd9ca3a6c..bc9f9a72e 100644 --- a/components/esp_matter/data_model_provider/clusters/push_av_stream_transport_integration.cpp +++ b/components/esp_matter/data_model_provider/clusters/push_av_stream_transport_integration.cpp @@ -56,7 +56,8 @@ void ESPMatterPushAvStreamTransportClusterServerInitCallback(EndpointId endpoint gServers[endpointId].Create(endpointId, BitFlags(rawFeatureMap)); CHIP_ERROR err = data_model::provider::get_instance().registry().Register(gServers[endpointId].Registration()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to register Push AV Stream Transport on endpoint %u: %" CHIP_ERROR_FORMAT, + ChipLogError(AppServer, + "Failed to register Push AV Stream Transport on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); } } @@ -69,10 +70,10 @@ void ESPMatterPushAvStreamTransportClusterServerShutdownCallback(EndpointId endp CHIP_ERROR err = data_model::provider::get_instance().registry().Unregister(&gServers[endpointId].Cluster()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to unregister Push AV Stream Transport on endpoint %u: %" CHIP_ERROR_FORMAT, + ChipLogError(AppServer, + "Failed to unregister Push AV Stream Transport on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); } - gServers[endpointId].Cluster().Deinit(); gServers[endpointId].Destroy(); } @@ -87,7 +88,7 @@ namespace PushAvStreamTransport { void SetDelegate(EndpointId endpointId, PushAvStreamTransportDelegate *delegate) { - gServers[endpointId].Cluster().SetDelegate(endpointId, delegate); + gServers[endpointId].Cluster().SetDelegate(delegate); gServers[endpointId].Cluster().Init(); } diff --git a/components/esp_matter/data_model_provider/clusters/software_diagnostics_integration.cpp b/components/esp_matter/data_model_provider/clusters/software_diagnostics_integration.cpp index 0be65ae6c..c2698a035 100644 --- a/components/esp_matter/data_model_provider/clusters/software_diagnostics_integration.cpp +++ b/components/esp_matter/data_model_provider/clusters/software_diagnostics_integration.cpp @@ -38,19 +38,25 @@ bool IsAttributeEnabled(EndpointId endpointId, AttributeId attributeId) void ESPMatterSoftwareDiagnosticsClusterServerInitCallback(EndpointId endpointId) { VerifyOrReturn(endpointId == kRootEndpointId); - const SoftwareDiagnosticsEnabledAttributes enabledAttributes{ - .enableThreadMetrics = IsAttributeEnabled(kRootEndpointId, Attributes::ThreadMetrics::Id), - .enableCurrentHeapFree = IsAttributeEnabled(kRootEndpointId, Attributes::CurrentHeapFree::Id), - .enableCurrentHeapUsed = IsAttributeEnabled(kRootEndpointId, Attributes::CurrentHeapUsed::Id), - .enableCurrentWatermarks = IsAttributeEnabled(kRootEndpointId, Attributes::CurrentHeapHighWatermark::Id), - }; + SoftwareDiagnosticsLogic::OptionalAttributeSet attrSet; + if (IsAttributeEnabled(kRootEndpointId, Attributes::ThreadMetrics::Id)) { + attrSet.Set(); + } + if (IsAttributeEnabled(kRootEndpointId, Attributes::CurrentHeapFree::Id)) { + attrSet.Set(); + } + if (IsAttributeEnabled(kRootEndpointId, Attributes::CurrentHeapUsed::Id)) { + attrSet.Set(); + } + if (IsAttributeEnabled(kRootEndpointId, Attributes::CurrentHeapHighWatermark::Id)) { + attrSet.Set(); + } - gServer.Create(enabledAttributes); + gServer.Create(attrSet); CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gServer.Registration()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to register SoftwareDiagnostics on endpoint %u: %" CHIP_ERROR_FORMAT, - endpointId, err.Format()); + ChipLogError(AppServer, "Failed to register SoftwareDiagnostics - Error: %" CHIP_ERROR_FORMAT, err.Format()); } } @@ -59,8 +65,7 @@ void ESPMatterSoftwareDiagnosticsClusterServerShutdownCallback(EndpointId endpoi VerifyOrReturn(endpointId == kRootEndpointId); CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServer.Cluster()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to unregister SoftwareDiagnostics on endpoint %u: %" CHIP_ERROR_FORMAT, - endpointId, err.Format()); + ChipLogError(AppServer, "Failed to unregister SoftwareDiagnostics - Error: %" CHIP_ERROR_FORMAT, err.Format()); } gServer.Destroy(); } diff --git a/components/esp_matter/data_model_provider/clusters/time_format_localization_integration.cpp b/components/esp_matter/data_model_provider/clusters/time_format_localization_integration.cpp new file mode 100644 index 000000000..9111e0def --- /dev/null +++ b/components/esp_matter/data_model_provider/clusters/time_format_localization_integration.cpp @@ -0,0 +1,96 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "esp_matter_data_model.h" +#include +#include +#include +#include "clusters/TimeFormatLocalization/Enums.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +LazyRegisteredServerCluster gServer; + +uint32_t get_feature_map(esp_matter::cluster_t *cluster) +{ + esp_matter::attribute_t *attribute = esp_matter::attribute::get(cluster, Globals::Attributes::FeatureMap::Id); + if (attribute) { + esp_matter_attr_val_t val = esp_matter_invalid(nullptr); + if (esp_matter::attribute::get_val(attribute, &val) == ESP_OK && val.type == ESP_MATTER_VAL_TYPE_BITMAP32) { + return val.val.u32; + } + } + return 0; +} + +TimeFormatLocalization::HourFormatEnum get_default_hour_format(esp_matter::cluster_t *cluster) +{ + esp_matter::attribute_t *attribute = + esp_matter::attribute::get(cluster, TimeFormatLocalization::Attributes::HourFormat::Id); + if (attribute) { + esp_matter_attr_val_t val = esp_matter_invalid(nullptr); + if (esp_matter::attribute::get_val(attribute, &val) == ESP_OK && val.type == ESP_MATTER_VAL_TYPE_ENUM8) { + return TimeFormatLocalization::HourFormatEnum(val.val.u8); + } + } + return TimeFormatLocalization::HourFormatEnum::kUseActiveLocale; +} + +TimeFormatLocalization::CalendarTypeEnum get_default_calendar_type(esp_matter::cluster_t *cluster) +{ + esp_matter::attribute_t *attribute = + esp_matter::attribute::get(cluster, TimeFormatLocalization::Attributes::ActiveCalendarType::Id); + if (attribute) { + esp_matter_attr_val_t val = esp_matter_invalid(nullptr); + if (esp_matter::attribute::get_val(attribute, &val) == ESP_OK && val.type == ESP_MATTER_VAL_TYPE_ENUM8) { + return TimeFormatLocalization::CalendarTypeEnum(val.val.u8); + } + } + return TimeFormatLocalization::CalendarTypeEnum::kUseActiveLocale; +} +} // namespace + +void ESPMatterTimeFormatLocalizationClusterServerInitCallback(EndpointId endpoint) +{ + // This cluster should only exist in Root endpoint. + VerifyOrReturn(endpoint == kRootEndpointId); + esp_matter::cluster_t *cluster = esp_matter::cluster::get(endpoint, TimeFormatLocalization::Id); + if (!cluster) { + return; + } + gServer.Create(endpoint, BitFlags(get_feature_map(cluster)), + get_default_hour_format(cluster), get_default_calendar_type(cluster)); + + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gServer.Registration()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "Failed to register TimeFormatLocalization - Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void ESPMatterTimeFormatLocalizationClusterServerShutdownCallback(EndpointId endpoint) +{ + // This cluster should only exist in Root endpoint. + VerifyOrReturn(endpoint == kRootEndpointId); + + CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServer.Cluster()); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "TimeFormatLocalization unregister error: %" CHIP_ERROR_FORMAT, err.Format()) + } + gServer.Destroy(); +} + +void MatterTimeFormatLocalizationPluginServerInitCallback() {} diff --git a/components/esp_matter/data_model_provider/clusters/wifi_network_diagnostic_integration.cpp b/components/esp_matter/data_model_provider/clusters/wifi_network_diagnostic_integration.cpp index 8c509bb6e..728523015 100644 --- a/components/esp_matter/data_model_provider/clusters/wifi_network_diagnostic_integration.cpp +++ b/components/esp_matter/data_model_provider/clusters/wifi_network_diagnostic_integration.cpp @@ -58,20 +58,21 @@ void ESPMatterWiFiNetworkDiagnosticsClusterServerInitCallback(EndpointId endpoin if (!IsClusterEnabled(endpointId) && gServers[endpointId].IsConstructed()) { return; } - WiFiNetworkDiagnosticsEnabledAttributes enabledAttributes{ - .enableCurrentMaxRate = IsAttributeEnabled(endpointId, WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::Id), - }; + WiFiDiagnosticsServerLogic::OptionalAttributeSet attrSet; + if (IsAttributeEnabled(endpointId, WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::Id)) { + attrSet.Set(); + } // NOTE: Currently, diagnostics only support a single provider (DeviceLayer::GetDiagnosticDataProvider()) // and do not properly support secondary network interfaces or per-endpoint diagnostics. // See issue:#40317 - gServers[endpointId].Create(endpointId, DeviceLayer::GetDiagnosticDataProvider(), enabledAttributes, + gServers[endpointId].Create(endpointId, DeviceLayer::GetDiagnosticDataProvider(), attrSet, BitFlags(GetFeatureMap(endpointId))); CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(gServers[endpointId].Registration()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to register WiFiNetworkDiagnostics on endpoint %u: %" CHIP_ERROR_FORMAT, endpointId, + ChipLogError(AppServer, "Failed to register WiFiNetworkDiagnostics on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); } } @@ -83,7 +84,7 @@ void ESPMatterWiFiNetworkDiagnosticsClusterServerShutdownCallback(EndpointId end CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&gServers[endpointId].Cluster()); if (err != CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to unregister WiFiNetworkDiagnostics on endpoint %u: %" CHIP_ERROR_FORMAT, endpointId, + ChipLogError(AppServer, "Failed to unregister WiFiNetworkDiagnostics on endpoint %u - Error: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); } diff --git a/components/esp_matter/data_model_provider/esp_matter_data_model_provider.cpp b/components/esp_matter/data_model_provider/esp_matter_data_model_provider.cpp index 614d32a2e..5aa0bddab 100644 --- a/components/esp_matter/data_model_provider/esp_matter_data_model_provider.cpp +++ b/components/esp_matter/data_model_provider/esp_matter_data_model_provider.cpp @@ -32,26 +32,14 @@ #include #include #include +#include +#include using namespace chip; using namespace chip::app; constexpr char TAG[] = "DataModelProvider"; -namespace chip { -namespace app { -class ContextAttributesChangeListener : public AttributesChangedListener { -public: - ContextAttributesChangeListener(const DataModel::InteractionModelContext &context) - : mListener(context.dataModelChangeListener) - { - } - void MarkDirty(const AttributePathParams &path) override { mListener->MarkDirty(path); } - -private: - DataModel::ProviderChangeListener *mListener; -}; - namespace { /// Attempts to read via an attribute access interface (AAI) /// @@ -107,8 +95,6 @@ std::optional TryWriteViaAccessInterface(const ConcreteDataAttribute return decoder.TriedDecode() ? std::make_optional(CHIP_NO_ERROR) : std::nullopt; } } // namespace -} // namespace app -} // namespace chip namespace { @@ -232,6 +218,7 @@ size_t get_attribute_count(esp_matter::cluster_t *cluster) return ret; } +DefaultAttributePersistenceProvider gDefaultAttributePersistence; } // anonymous namespace namespace esp_matter { @@ -247,6 +234,7 @@ provider &provider::get_instance() CHIP_ERROR provider::Startup(InteractionModelContext context) { ReturnErrorOnFailure(DataModel::Provider::Startup(context)); + mContext.emplace(context); esp_matter::cluster::add_bounds_callback_common(); esp_matter::cluster::plugin_init_callback_common(); endpoint_t *ep = endpoint::get_first(node::get()); @@ -269,24 +257,27 @@ CHIP_ERROR provider::Startup(InteractionModelContext context) } ep = endpoint::get_next(ep); } - - return m_registry.SetContext(ServerClusterContext{ - .provider = this, - .storage = nullptr, - .attributeStorage = nullptr, - .interactionContext = &mContext, + if (GetAttributePersistenceProvider() == nullptr) { + gDefaultAttributePersistence.Init(&Server::GetInstance().GetPersistentStorage()); + SetAttributePersistenceProvider(&gDefaultAttributePersistence); + } + return mRegistry.SetContext(ServerClusterContext{ + .provider = *this, + .storage = Server::GetInstance().GetPersistentStorage(), + .attributeStorage = *GetAttributePersistenceProvider(), + .interactionContext = *mContext, }); } CHIP_ERROR provider::Shutdown() { - m_registry.ClearContext(); + mRegistry.ClearContext(); return CHIP_NO_ERROR; } ActionReturnStatus provider::ReadAttribute(const ReadAttributeRequest &request, AttributeValueEncoder &encoder) { - if (auto *cluster = m_registry.Get(request.path); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(request.path); cluster != nullptr) { return cluster->ReadAttribute(request, encoder); } Status status = CheckDataModelPath(request.path); @@ -308,7 +299,7 @@ ActionReturnStatus provider::ReadAttribute(const ReadAttributeRequest &request, ActionReturnStatus provider::WriteAttribute(const WriteAttributeRequest &request, AttributeValueDecoder &decoder) { - if (auto *cluster = m_registry.Get(request.path); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(request.path); cluster != nullptr) { return cluster->WriteAttribute(request, decoder); } Status status = CheckDataModelPath(request.path); @@ -323,7 +314,6 @@ ActionReturnStatus provider::WriteAttribute(const WriteAttributeRequest &request VerifyOrReturnValue(data_version == request.path.mDataVersion.Value(), Protocols::InteractionModel::Status::DataVersionMismatch); } - ContextAttributesChangeListener change_listener(CurrentContext()); AttributeAccessInterface *aai = AttributeAccessInterfaceRegistry::Instance().Get(request.path.mEndpointId, request.path.mClusterId); @@ -332,7 +322,7 @@ ActionReturnStatus provider::WriteAttribute(const WriteAttributeRequest &request if (*aai_result == CHIP_NO_ERROR) { cluster::increase_data_version(cluster); AttributePathParams path(request.path.mEndpointId, request.path.mClusterId, request.path.mAttributeId); - change_listener.MarkDirty(path); + mContext->dataModelChangeListener.MarkDirty(path); } return *aai_result; } @@ -353,7 +343,7 @@ ActionReturnStatus provider::WriteAttribute(const WriteAttributeRequest &request void provider::ListAttributeWriteNotification(const ConcreteAttributePath &aPath, ListWriteOperation opType) { - if (auto *cluster = m_registry.Get(aPath); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(aPath); cluster != nullptr) { return cluster->ListAttributeWriteNotification(aPath, opType); } AttributeAccessInterface *aai = @@ -378,7 +368,7 @@ std::optional provider::InvokeCommand(const InvokeRequest &r chip::TLV::TLVReader &input_arguments, CommandHandler *handler) { - if (auto *cluster = m_registry.Get(request.path); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(request.path); cluster != nullptr) { return cluster->InvokeCommand(request, input_arguments, handler); } Status status = CheckDataModelPath(request.path); @@ -486,8 +476,13 @@ CHIP_ERROR provider::ServerClusters(EndpointId endpointId, ReadOnlyBufferBuilder if (cluster::get_flags(cluster) & CLUSTER_FLAG_SERVER) { ServerClusterEntry entry; entry.clusterId = cluster::get_id(cluster); - entry.flags.ClearAll(); - VerifyOrReturnError(cluster::get_data_version(cluster, entry.dataVersion) == ESP_OK, CHIP_ERROR_INTERNAL); + if (auto *server_cluster = mRegistry.Get(ConcreteClusterPath(endpointId, entry.clusterId)); server_cluster != nullptr) { + entry.flags = server_cluster->GetClusterFlags(ConcreteClusterPath(endpointId, entry.clusterId)); + entry.dataVersion = server_cluster->GetDataVersion(ConcreteClusterPath(endpointId, entry.clusterId)); + } else { + entry.flags.ClearAll(); + VerifyOrReturnError(cluster::get_data_version(cluster, entry.dataVersion) == ESP_OK, CHIP_ERROR_INTERNAL); + } ReturnErrorOnFailure(builder.Append(entry)); } cluster = cluster::get_next(cluster); @@ -506,7 +501,7 @@ CHIP_ERROR provider::EndpointUniqueID(EndpointId endpointId, MutableCharSpan &ep CHIP_ERROR provider::EventInfo(const ConcreteEventPath &path, EventEntry &eventInfo) { - if (auto *cluster = m_registry.Get(path); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(path); cluster != nullptr) { return cluster->EventInfo(path, eventInfo); } Status status = CheckDataModelPath(path); @@ -518,7 +513,7 @@ CHIP_ERROR provider::EventInfo(const ConcreteEventPath &path, EventEntry &eventI CHIP_ERROR provider::GeneratedCommands(const ConcreteClusterPath &path, ReadOnlyBufferBuilder &builder) { - if (auto *cluster = m_registry.Get(path); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(path); cluster != nullptr) { return cluster->GeneratedCommands(path, builder); } Status status = CheckDataModelPath(path); @@ -540,7 +535,7 @@ CHIP_ERROR provider::GeneratedCommands(const ConcreteClusterPath &path, ReadOnly CHIP_ERROR provider::AcceptedCommands(const ConcreteClusterPath &path, ReadOnlyBufferBuilder &builder) { - if (auto *cluster = m_registry.Get(path); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(path); cluster != nullptr) { return cluster->AcceptedCommands(path, builder); } Status status = CheckDataModelPath(path); @@ -549,57 +544,9 @@ CHIP_ERROR provider::AcceptedCommands(const ConcreteClusterPath &path, CommandHandlerInterface *interface = CommandHandlerInterfaceRegistry::Instance().GetCommandHandler(path.mEndpointId, path.mClusterId); if (interface != nullptr) { - size_t commandCount = 0; - CHIP_ERROR err = interface->EnumerateAcceptedCommands( - path, - [](CommandId id, void *context) -> Loop { - *reinterpret_cast(context) += 1; - return Loop::Continue; - }, - reinterpret_cast(&commandCount)); - - if (err == CHIP_NO_ERROR) { - using EnumerationData = struct { - ConcreteCommandPath commandPath; - ReadOnlyBufferBuilder *acceptedCommandList; - CHIP_ERROR processingError; - }; - - EnumerationData enumerationData; - enumerationData.commandPath = ConcreteCommandPath(path.mEndpointId, path.mClusterId, kInvalidCommandId); - enumerationData.processingError = CHIP_NO_ERROR; - enumerationData.acceptedCommandList = &builder; - - ReturnErrorOnFailure(builder.EnsureAppendCapacity(commandCount)); - - ReturnErrorOnFailure(interface->EnumerateAcceptedCommands( - path, - [](CommandId commandId, void *context) -> Loop { - auto input = reinterpret_cast(context); - input->commandPath.mCommandId = commandId; - ClusterId clusterId = input->commandPath.mClusterId; - BitMask quality_flags; - quality_flags - .Set(DataModel::CommandQualityFlags::kFabricScoped, CommandIsFabricScoped(clusterId, commandId)) - .Set(DataModel::CommandQualityFlags::kTimed, CommandNeedsTimedInvoke(clusterId, commandId)) - .Set(DataModel::CommandQualityFlags::kLargeMessage, - CommandHasLargePayload(clusterId, commandId)); - AcceptedCommandEntry entry( - commandId, quality_flags, - MatterGetAccessPrivilegeForInvokeCommand(input->commandPath.mClusterId, commandId)); - CHIP_ERROR appendError = input->acceptedCommandList->Append(entry); - if (appendError != CHIP_NO_ERROR) { - input->processingError = appendError; - return Loop::Break; - } - return Loop::Continue; - }, - reinterpret_cast(&enumerationData))); - ReturnErrorOnFailure(enumerationData.processingError); - // the two invocations MUST return the same sizes. - VerifyOrReturnError(builder.Size() == commandCount, CHIP_ERROR_INTERNAL); - return CHIP_NO_ERROR; - } + CHIP_ERROR err = interface->RetrieveAcceptedCommands(path, builder); + // If retrieving the accepted commands returns CHIP_ERROR_NOT_IMPLEMENTED then continue with normal processing. + // Otherwise we finished. VerifyOrReturnError(err == CHIP_ERROR_NOT_IMPLEMENTED, err); } // If we cannot get AcceptedCommands array from CommandHandlerinterface, get it from esp_matter data model. @@ -634,7 +581,7 @@ static constexpr size_t k_global_attributes_count = CHIP_ERROR provider::Attributes(const ConcreteClusterPath &path, ReadOnlyBufferBuilder &builder) { - if (auto *cluster = m_registry.Get(path); cluster != nullptr) { + if (auto *cluster = mRegistry.Get(path); cluster != nullptr) { return cluster->Attributes(path, builder); } Status status = CheckDataModelPath(path); @@ -677,8 +624,7 @@ 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); - ContextAttributesChangeListener change_listener(CurrentContext()); - change_listener.MarkDirty(path); + mContext->dataModelChangeListener.MarkDirty(path); } Status provider::CheckDataModelPath(EndpointId endpointId) diff --git a/components/esp_matter/data_model_provider/esp_matter_data_model_provider.h b/components/esp_matter/data_model_provider/esp_matter_data_model_provider.h index 7be3ada88..35b821e5d 100644 --- a/components/esp_matter/data_model_provider/esp_matter_data_model_provider.h +++ b/components/esp_matter/data_model_provider/esp_matter_data_model_provider.h @@ -67,7 +67,7 @@ public: // access to the typed global singleton of this class. static provider &get_instance(); - chip::app::ServerClusterInterfaceRegistry ®istry() { return m_registry; } + chip::app::ServerClusterInterfaceRegistry ®istry() { return mRegistry; } /// Generic model implementations CHIP_ERROR Startup(InteractionModelContext context) override; @@ -104,7 +104,8 @@ private: Status CheckDataModelPath(const ConcreteEventPath &path); Status CheckDataModelPath(const chip::app::ConcreteCommandPath path); - chip::app::ServerClusterInterfaceRegistry m_registry; + chip::app::ServerClusterInterfaceRegistry mRegistry; + std::optional mContext; }; } // namespace data_model diff --git a/components/esp_matter/data_model_provider/esp_matter_ember_stubs.cpp b/components/esp_matter/data_model_provider/esp_matter_ember_stubs.cpp index 920ef3361..5b4a64dba 100644 --- a/components/esp_matter/data_model_provider/esp_matter_ember_stubs.cpp +++ b/components/esp_matter/data_model_provider/esp_matter_ember_stubs.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -878,260 +877,6 @@ EmberAfAttributeType AttributeBaseType(EmberAfAttributeType type) } // namespace app } // namespace chip -// TODO: Remove the BindingTable definition when binding cluster is decoupled from ember. -namespace chip { - -BindingTable BindingTable::sInstance; - -BindingTable::BindingTable() -{ - memset(mNextIndex, kNextNullIndex, sizeof(mNextIndex)); -} - -CHIP_ERROR BindingTable::Add(const EmberBindingTableEntry &entry) -{ - if (entry.type == MATTER_UNUSED_BINDING) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - uint8_t newIndex = MATTER_BINDING_TABLE_SIZE; - for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++) { - if (mBindingTable[i].type == MATTER_UNUSED_BINDING) { - newIndex = i; - } - } - if (newIndex >= MATTER_BINDING_TABLE_SIZE) { - return CHIP_ERROR_NO_MEMORY; - } - mBindingTable[newIndex] = entry; - CHIP_ERROR error = SaveEntryToStorage(newIndex, kNextNullIndex); - if (error == CHIP_NO_ERROR) { - if (mTail == kNextNullIndex) { - error = SaveListInfo(newIndex); - } else { - error = SaveEntryToStorage(mTail, newIndex); - } - if (error != CHIP_NO_ERROR) { - mStorage->SyncDeleteKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(newIndex).KeyName()); - } - } - if (error != CHIP_NO_ERROR) { - // Roll back - mBindingTable[newIndex].type = MATTER_UNUSED_BINDING; - return error; - } - - if (mTail == kNextNullIndex) { - mTail = newIndex; - mHead = newIndex; - } else { - mNextIndex[mTail] = newIndex; - mNextIndex[newIndex] = kNextNullIndex; - mTail = newIndex; - } - - mSize++; - return CHIP_NO_ERROR; -} - -const EmberBindingTableEntry &BindingTable::GetAt(uint8_t index) -{ - return mBindingTable[index]; -} - -CHIP_ERROR BindingTable::SaveEntryToStorage(uint8_t index, uint8_t nextIndex) -{ - EmberBindingTableEntry &entry = mBindingTable[index]; - uint8_t buffer[kEntryStorageSize] = {0}; - TLV::TLVWriter writer; - writer.Init(buffer); - TLV::TLVType container; - ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::TLVType::kTLVType_Structure, container)); - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagFabricIndex), entry.fabricIndex)); - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagLocalEndpoint), entry.local)); - if (entry.clusterId.has_value()) { - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagCluster), *entry.clusterId)); - } - if (entry.type == MATTER_UNICAST_BINDING) { - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagRemoteEndpoint), entry.remote)); - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagNodeId), entry.nodeId)); - } else { - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagGroupId), entry.groupId)); - } - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagNextEntry), nextIndex)); - ReturnErrorOnFailure(writer.EndContainer(container)); - ReturnErrorOnFailure(writer.Finalize()); - return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(index).KeyName(), buffer, - static_cast(writer.GetLengthWritten())); -} - -CHIP_ERROR BindingTable::SaveListInfo(uint8_t head) -{ - uint8_t buffer[kListInfoStorageSize] = {0}; - TLV::TLVWriter writer; - writer.Init(buffer); - TLV::TLVType container; - ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::TLVType::kTLVType_Structure, container)); - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagStorageVersion), kStorageVersion)); - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagHead), head)); - ReturnErrorOnFailure(writer.EndContainer(container)); - ReturnErrorOnFailure(writer.Finalize()); - return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::BindingTable().KeyName(), buffer, - static_cast(writer.GetLengthWritten())); -} - -CHIP_ERROR BindingTable::LoadFromStorage() -{ - VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE); - uint8_t buffer[kListInfoStorageSize] = {0}; - uint16_t size = sizeof(buffer); - CHIP_ERROR error; - - ReturnErrorOnFailure(mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::BindingTable().KeyName(), buffer, size)); - TLV::TLVReader reader; - reader.Init(buffer, size); - - ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())); - - TLV::TLVType container; - ReturnErrorOnFailure(reader.EnterContainer(container)); - - ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagStorageVersion))); - uint32_t version; - ReturnErrorOnFailure(reader.Get(version)); - VerifyOrReturnError(version == kStorageVersion, CHIP_ERROR_VERSION_MISMATCH); - ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagHead))); - uint8_t index; - ReturnErrorOnFailure(reader.Get(index)); - mHead = index; - while (index != kNextNullIndex) { - uint8_t nextIndex; - error = LoadEntryFromStorage(index, nextIndex); - if (error != CHIP_NO_ERROR) { - mHead = kNextNullIndex; - mTail = kNextNullIndex; - return error; - } - mTail = index; - index = nextIndex; - mSize++; - } - error = reader.ExitContainer(container); - if (error != CHIP_NO_ERROR) { - mHead = kNextNullIndex; - mTail = kNextNullIndex; - } - return error; -} - -CHIP_ERROR BindingTable::LoadEntryFromStorage(uint8_t index, uint8_t &nextIndex) -{ - uint8_t buffer[kEntryStorageSize] = {0}; - uint16_t size = sizeof(buffer); - EmberBindingTableEntry entry; - - ReturnErrorOnFailure( - mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(index).KeyName(), buffer, size)); - TLV::TLVReader reader; - reader.Init(buffer, size); - - ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())); - - TLV::TLVType container; - ReturnErrorOnFailure(reader.EnterContainer(container)); - ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagFabricIndex))); - ReturnErrorOnFailure(reader.Get(entry.fabricIndex)); - ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagLocalEndpoint))); - ReturnErrorOnFailure(reader.Get(entry.local)); - ReturnErrorOnFailure(reader.Next()); - if (reader.GetTag() == TLV::ContextTag(kTagCluster)) { - ClusterId clusterId; - ReturnErrorOnFailure(reader.Get(clusterId)); - entry.clusterId.emplace(clusterId); - ReturnErrorOnFailure(reader.Next()); - } else { - entry.clusterId = std::nullopt; - } - if (reader.GetTag() == TLV::ContextTag(kTagRemoteEndpoint)) { - entry.type = MATTER_UNICAST_BINDING; - ReturnErrorOnFailure(reader.Get(entry.remote)); - ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagNodeId))); - ReturnErrorOnFailure(reader.Get(entry.nodeId)); - } else { - entry.type = MATTER_MULTICAST_BINDING; - VerifyOrReturnError(reader.GetTag() == TLV::ContextTag(kTagGroupId), CHIP_ERROR_INVALID_TLV_TAG); - ReturnErrorOnFailure(reader.Get(entry.groupId)); - } - ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagNextEntry))); - ReturnErrorOnFailure(reader.Get(nextIndex)); - ReturnErrorOnFailure(reader.ExitContainer(container)); - mBindingTable[index] = entry; - mNextIndex[index] = nextIndex; - return CHIP_NO_ERROR; -} - -CHIP_ERROR BindingTable::RemoveAt(Iterator &iter) -{ - CHIP_ERROR error; - if (iter.mTable != this || iter.mIndex == kNextNullIndex) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - if (iter.mIndex == mTail) { - mTail = iter.mPrevIndex; - } - uint8_t next = mNextIndex[iter.mIndex]; - if (iter.mIndex != mHead) { - error = SaveEntryToStorage(iter.mPrevIndex, next); - if (error == CHIP_NO_ERROR) { - mNextIndex[iter.mPrevIndex] = next; - } - } else { - error = SaveListInfo(next); - if (error == CHIP_NO_ERROR) { - mHead = next; - } - } - if (error == CHIP_NO_ERROR) { - // The remove is considered "submitted" once the change on prev node takes effect - if (mStorage->SyncDeleteKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(iter.mIndex).KeyName()) != - CHIP_NO_ERROR) { - ChipLogError(AppServer, "Failed to remove binding table entry %u from storage", iter.mIndex); - } - mBindingTable[iter.mIndex].type = MATTER_UNUSED_BINDING; - mNextIndex[iter.mIndex] = kNextNullIndex; - mSize--; - } - iter.mIndex = next; - return error; -} - -BindingTable::Iterator BindingTable::begin() -{ - Iterator iter; - iter.mTable = this; - iter.mPrevIndex = kNextNullIndex; - iter.mIndex = mHead; - return iter; -} - -BindingTable::Iterator BindingTable::end() -{ - Iterator iter; - iter.mTable = this; - iter.mIndex = kNextNullIndex; - return iter; -} - -BindingTable::Iterator BindingTable::Iterator::operator++() -{ - if (mIndex != kNextNullIndex) { - mPrevIndex = mIndex; - mIndex = mTable->mNextIndex[mIndex]; - } - return *this; -} - -} // namespace chip - // Override Ember functions // TODO: Remove the emberAfEndpointIndexIsEnabled and emberAfEndpointCount functions when FabricTableImpl is decoupled diff --git a/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp b/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp index aaeae8720..b600985d1 100644 --- a/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp +++ b/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp @@ -16,7 +16,6 @@ // Cluster init functions that don't have a cluster implementation to define // them in. void MatterBallastConfigurationPluginServerInitCallback() {} -void MatterBooleanStatePluginServerInitCallback() {} void MatterRelativeHumidityMeasurementPluginServerInitCallback() {} void MatterIlluminanceMeasurementPluginServerInitCallback() {} void MatterBinaryInputBasicPluginServerInitCallback() {} diff --git a/components/esp_matter/esp_matter_client.cpp b/components/esp_matter/esp_matter_client.cpp index 0a5c8b9be..6dd9e2507 100644 --- a/components/esp_matter/esp_matter_client.cpp +++ b/components/esp_matter/esp_matter_client.cpp @@ -53,7 +53,6 @@ namespace client { static request_callback_t client_request_callback = NULL; static group_request_callback_t client_group_request_callback = NULL; static void *request_callback_priv_data; -static bool initialize_binding_manager = false; esp_err_t set_request_callback(request_callback_t callback, group_request_callback_t g_callback, void *priv_data) { @@ -194,15 +193,11 @@ static void __binding_manager_init(intptr_t arg) void binding_manager_init() { - if (initialize_binding_manager) { +#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL + if (endpoint::get_cluster_count(chip::kInvalidEndpointId, Binding::Id, CLUSTER_FLAG_SERVER) > 0) { chip::DeviceLayer::PlatformMgr().ScheduleWork(__binding_manager_init); - initialize_binding_manager = false; } -} - -void binding_init() -{ - initialize_binding_manager = true; +#endif // CONFIG_ESP_MATTER_ENABLE_DATA_MODEL } #endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER diff --git a/components/esp_matter/esp_matter_client.h b/components/esp_matter/esp_matter_client.h index 5be62ea0c..8eb56fd40 100644 --- a/components/esp_matter/esp_matter_client.h +++ b/components/esp_matter/esp_matter_client.h @@ -97,19 +97,24 @@ typedef void (*request_callback_t)(peer_device_t *peer_device, request_handle_t typedef void (*group_request_callback_t)(uint8_t fabric_index, request_handle_t *req_handle, void *priv_data); #ifdef CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER -/** Initialize binding - * - * This should be called if the Binding cluster has been created. It just sets a flag for the binding manager to be - * initialized. - * If the cluster::binding::create() is being used, this is called internally. - */ -void binding_init(); - /** Initialize binding manager * * This initializes the binding manager. It is called after the matter thread has been started. */ void binding_manager_init(); + +/** Cluster update + * + * For an already binded device, this API can be used to get the request send callback, and the send_request APIs can + * then be called from the callback. + * + * @param[in] local_endpoint_id The ID of the local endpoint with a binding cluster. + * @param[in] req_handle Request information to notify the bound cluster changed. + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t cluster_update(uint16_t local_endpoint_id, request_handle_t *req_handle); #endif // CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER /** Connect @@ -155,19 +160,6 @@ esp_err_t group_request_send(uint8_t fabric_index, request_handle_t *req_handle) */ esp_err_t set_request_callback(request_callback_t callback, group_request_callback_t g_callback, void *priv_data); -/** Cluster update - * - * For an already binded device, this API can be used to get the request send callback, and the send_request APIs can - * then be called from the callback. - * - * @param[in] local_endpoint_id The ID of the local endpoint with a binding cluster. - * @param[in] req_handle Request information to notify the bound cluster changed. - * - * @return ESP_OK on success. - * @return error in case of failure. - */ -esp_err_t cluster_update(uint16_t local_endpoint_id, request_handle_t *req_handle); - namespace interaction { using chip::Optional; diff --git a/components/esp_matter/utils/cluster_select/Kconfig.in b/components/esp_matter/utils/cluster_select/Kconfig.in index 67ccf557b..4f4f687e7 100644 --- a/components/esp_matter/utils/cluster_select/Kconfig.in +++ b/components/esp_matter/utils/cluster_select/Kconfig.in @@ -45,6 +45,10 @@ config SUPPORT_BINDING_CLUSTER bool "Support BINDING_CLUSTER" default y +config SUPPORT_BOOLEAN_STATE_CLUSTER + bool "Support BOOLEAN_STATE_CLUSTER" + default y + config SUPPORT_BOOLEAN_STATE_CONFIGURATION_CLUSTER bool "Support BOOLEAN_STATE_CONFIGURATION_CLUSTER" default y @@ -445,6 +449,10 @@ config SUPPORT_TIMER_CLUSTER bool "Support TIMER_CLUSTER" default y +config SUPPORT_TLS_CERTIFICATE_MANAGEMENT_CLUSTER + bool "Support TLS_CERTIFICATE_MANAGEMENT_CLUSTER" + default y + config SUPPORT_TLS_CLIENT_MANAGEMENT_CLUSTER bool "Support TLS_CLIENT_MANAGEMENT_CLUSTER" default y diff --git a/components/esp_matter/utils/cluster_select/cluster_dir.cmake b/components/esp_matter/utils/cluster_select/cluster_dir.cmake index a9e2e33b8..d47dd3b5e 100644 --- a/components/esp_matter/utils/cluster_select/cluster_dir.cmake +++ b/components/esp_matter/utils/cluster_select/cluster_dir.cmake @@ -36,6 +36,9 @@ function(get_supported_cluster_dirs source_dirs) if(CONFIG_SUPPORT_BINDING_CLUSTER) list(APPEND temp_list "${MATTER_SDK_PATH}/src/app/clusters/bindings") endif() + if(CONFIG_SUPPORT_BOOLEAN_STATE_CLUSTER) + list(APPEND temp_list "${MATTER_SDK_PATH}/src/app/clusters/boolean-state-server") + endif() if(CONFIG_SUPPORT_BOOLEAN_STATE_CONFIGURATION_CLUSTER) list(APPEND temp_list "${MATTER_SDK_PATH}/src/app/clusters/boolean-state-configuration-server") endif() @@ -336,6 +339,9 @@ function(get_supported_cluster_dirs source_dirs) if(CONFIG_SUPPORT_TIMER_CLUSTER) list(APPEND temp_list "${MATTER_SDK_PATH}/src/app/clusters/timer-server") endif() + if(CONFIG_SUPPORT_TLS_CERTIFICATE_MANAGEMENT_CLUSTER) + list(APPEND temp_list "${MATTER_SDK_PATH}/src/app/clusters/tls-certificate-management-server") + endif() if(CONFIG_SUPPORT_TLS_CLIENT_MANAGEMENT_CLUSTER) list(APPEND temp_list "${MATTER_SDK_PATH}/src/app/clusters/tls-client-management-server") endif() diff --git a/components/esp_matter/zap_common/app/ClusterCallbacks.h b/components/esp_matter/zap_common/app/ClusterCallbacks.h index 38851c38e..ec94daa23 100644 --- a/components/esp_matter/zap_common/app/ClusterCallbacks.h +++ b/components/esp_matter/zap_common/app/ClusterCallbacks.h @@ -166,6 +166,9 @@ void ESPMatterGeneralDiagnosticsClusterServerShutdownCallback(EndpointId endpoin void ESPMatterGroupKeyManagementClusterServerInitCallback(EndpointId endpoint); void ESPMatterGroupKeyManagementClusterServerShutdownCallback(EndpointId endpoint); +void ESPMatterGroupcastClusterServerInitCallback(EndpointId endpoint); +void ESPMatterGroupcastClusterServerShutdownCallback(EndpointId endpoint); + void ESPMatterGroupsClusterServerInitCallback(EndpointId endpoint); void ESPMatterGroupsClusterServerShutdownCallback(EndpointId endpoint); diff --git a/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h b/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h index bbfeb2c72..0b9c96554 100644 --- a/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h +++ b/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h @@ -53,6 +53,7 @@ void MatterFormaldehydeConcentrationMeasurementPluginServerInitCallback(); void MatterGeneralCommissioningPluginServerInitCallback(); void MatterGeneralDiagnosticsPluginServerInitCallback(); void MatterGroupKeyManagementPluginServerInitCallback(); +void MatterGroupcastPluginServerInitCallback(); void MatterGroupsPluginServerInitCallback(); void MatterHepaFilterMonitoringPluginServerInitCallback(); void MatterIcdManagementPluginServerInitCallback(); diff --git a/components/esp_matter/zap_common/zap-generated/access.h b/components/esp_matter/zap_common/zap-generated/access.h index c75f6cfcd..3c9e407e3 100644 --- a/components/esp_matter/zap_common/zap-generated/access.h +++ b/components/esp_matter/zap_common/zap-generated/access.h @@ -625,6 +625,11 @@ 0x00000062, /* Cluster: Scenes Management, Command: RemoveAllScenes, Privilege: manage */ \ 0x00000062, /* Cluster: Scenes Management, Command: StoreScene, Privilege: manage */ \ 0x00000062, /* Cluster: Scenes Management, Command: CopyScene, Privilege: manage */ \ + 0x00000065, /* Cluster: Groupcast, Command: JoinGroup, Privilege: manage */ \ + 0x00000065, /* Cluster: Groupcast, Command: LeaveGroup, Privilege: manage */ \ + 0x00000065, /* Cluster: Groupcast, Command: UpdateGroupKey, Privilege: manage */ \ + 0x00000065, /* Cluster: Groupcast, Command: ExpireGracePeriod, Privilege: manage */ \ + 0x00000065, /* Cluster: Groupcast, Command: ConfigureAuxiliaryACL, Privilege: administer */ \ 0x00000094, /* Cluster: Water Heater Management, Command: Boost, Privilege: manage */ \ 0x00000094, /* Cluster: Water Heater Management, Command: CancelBoost, Privilege: manage */ \ 0x00000101, /* Cluster: Door Lock, Command: SetWeekDaySchedule, Privilege: administer */ \ @@ -710,7 +715,7 @@ 0x00000753, /* Cluster: Joint Fabric Administrator, Command: AnnounceJointFabricAdministrator, Privilege: administer */ \ 0x00000801, /* Cluster: TLS Certificate Management, Command: ProvisionRootCertificate, Privilege: administer */ \ 0x00000801, /* Cluster: TLS Certificate Management, Command: RemoveRootCertificate, Privilege: administer */ \ - 0x00000801, /* Cluster: TLS Certificate Management, Command: TLSClientCSR, Privilege: administer */ \ + 0x00000801, /* Cluster: TLS Certificate Management, Command: ClientCSR, Privilege: administer */ \ 0x00000801, /* Cluster: TLS Certificate Management, Command: ProvisionClientCertificate, Privilege: administer */ \ 0x00000801, /* Cluster: TLS Certificate Management, Command: RemoveClientCertificate, Privilege: administer */ \ 0x00000802, /* Cluster: TLS Client Management, Command: ProvisionEndpoint, Privilege: administer */ \ @@ -775,6 +780,11 @@ 0x00000003, /* Cluster: Scenes Management, Command: RemoveAllScenes, Privilege: manage */ \ 0x00000004, /* Cluster: Scenes Management, Command: StoreScene, Privilege: manage */ \ 0x00000040, /* Cluster: Scenes Management, Command: CopyScene, Privilege: manage */ \ + 0x00000000, /* Cluster: Groupcast, Command: JoinGroup, Privilege: manage */ \ + 0x00000001, /* Cluster: Groupcast, Command: LeaveGroup, Privilege: manage */ \ + 0x00000003, /* Cluster: Groupcast, Command: UpdateGroupKey, Privilege: manage */ \ + 0x00000004, /* Cluster: Groupcast, Command: ExpireGracePeriod, Privilege: manage */ \ + 0x00000005, /* Cluster: Groupcast, Command: ConfigureAuxiliaryACL, Privilege: administer */ \ 0x00000000, /* Cluster: Water Heater Management, Command: Boost, Privilege: manage */ \ 0x00000001, /* Cluster: Water Heater Management, Command: CancelBoost, Privilege: manage */ \ 0x0000000B, /* Cluster: Door Lock, Command: SetWeekDaySchedule, Privilege: administer */ \ @@ -860,7 +870,7 @@ 0x00000008, /* Cluster: Joint Fabric Administrator, Command: AnnounceJointFabricAdministrator, Privilege: administer */ \ 0x00000000, /* Cluster: TLS Certificate Management, Command: ProvisionRootCertificate, Privilege: administer */ \ 0x00000006, /* Cluster: TLS Certificate Management, Command: RemoveRootCertificate, Privilege: administer */ \ - 0x00000007, /* Cluster: TLS Certificate Management, Command: TLSClientCSR, Privilege: administer */ \ + 0x00000007, /* Cluster: TLS Certificate Management, Command: ClientCSR, Privilege: administer */ \ 0x00000009, /* Cluster: TLS Certificate Management, Command: ProvisionClientCertificate, Privilege: administer */ \ 0x0000000E, /* Cluster: TLS Certificate Management, Command: RemoveClientCertificate, Privilege: administer */ \ 0x00000000, /* Cluster: TLS Client Management, Command: ProvisionEndpoint, Privilege: administer */ \ @@ -925,6 +935,11 @@ chip::Access::Privilege::kManage, /* Cluster: Scenes Management, Command: RemoveAllScenes, Privilege: manage */ \ chip::Access::Privilege::kManage, /* Cluster: Scenes Management, Command: StoreScene, Privilege: manage */ \ chip::Access::Privilege::kManage, /* Cluster: Scenes Management, Command: CopyScene, Privilege: manage */ \ + chip::Access::Privilege::kManage, /* Cluster: Groupcast, Command: JoinGroup, Privilege: manage */ \ + chip::Access::Privilege::kManage, /* Cluster: Groupcast, Command: LeaveGroup, Privilege: manage */ \ + chip::Access::Privilege::kManage, /* Cluster: Groupcast, Command: UpdateGroupKey, Privilege: manage */ \ + chip::Access::Privilege::kManage, /* Cluster: Groupcast, Command: ExpireGracePeriod, Privilege: manage */ \ + chip::Access::Privilege::kAdminister, /* Cluster: Groupcast, Command: ConfigureAuxiliaryACL, Privilege: administer */ \ chip::Access::Privilege::kManage, /* Cluster: Water Heater Management, Command: Boost, Privilege: manage */ \ chip::Access::Privilege::kManage, /* Cluster: Water Heater Management, Command: CancelBoost, Privilege: manage */ \ chip::Access::Privilege::kAdminister, /* Cluster: Door Lock, Command: SetWeekDaySchedule, Privilege: administer */ \ @@ -1010,7 +1025,7 @@ chip::Access::Privilege::kAdminister, /* Cluster: Joint Fabric Administrator, Command: AnnounceJointFabricAdministrator, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: TLS Certificate Management, Command: ProvisionRootCertificate, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: TLS Certificate Management, Command: RemoveRootCertificate, Privilege: administer */ \ - chip::Access::Privilege::kAdminister, /* Cluster: TLS Certificate Management, Command: TLSClientCSR, Privilege: administer */ \ + chip::Access::Privilege::kAdminister, /* Cluster: TLS Certificate Management, Command: ClientCSR, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: TLS Certificate Management, Command: ProvisionClientCertificate, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: TLS Certificate Management, Command: RemoveClientCertificate, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: TLS Client Management, Command: ProvisionEndpoint, Privilege: administer */ \ diff --git a/connectedhomeip/connectedhomeip b/connectedhomeip/connectedhomeip index bdc38cd77..f902839ab 160000 --- a/connectedhomeip/connectedhomeip +++ b/connectedhomeip/connectedhomeip @@ -1 +1 @@ -Subproject commit bdc38cd772964c67b43060cc399a2fe531529c39 +Subproject commit f902839abf1de0d17956de34889b6ad997e2c5e4 diff --git a/examples/common/blemesh_platform/platform/ESP32_custom/BUILD.gn b/examples/common/blemesh_platform/platform/ESP32_custom/BUILD.gn index aaf8b5126..d9ffc1078 100644 --- a/examples/common/blemesh_platform/platform/ESP32_custom/BUILD.gn +++ b/examples/common/blemesh_platform/platform/ESP32_custom/BUILD.gn @@ -121,7 +121,6 @@ static_library("ESP32_custom") { "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", "Logging.cpp", - "LwIPCoreLock.cpp", "PlatformManagerImpl.cpp", "PlatformManagerImpl.h", "SystemTimeSupport.cpp", diff --git a/examples/common/blemesh_platform/platform/ESP32_custom/LwIPCoreLock.cpp b/examples/common/blemesh_platform/platform/ESP32_custom/LwIPCoreLock.cpp deleted file mode 120000 index bedaac190..000000000 --- a/examples/common/blemesh_platform/platform/ESP32_custom/LwIPCoreLock.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/LwIPCoreLock.cpp \ No newline at end of file diff --git a/examples/common/external_platform/BUILD.gn b/examples/common/external_platform/BUILD.gn index 397399c14..8211214c3 100644 --- a/examples/common/external_platform/BUILD.gn +++ b/examples/common/external_platform/BUILD.gn @@ -116,7 +116,6 @@ static_library("ESP32_custom") { "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", "Logging.cpp", - "LwIPCoreLock.cpp", "PlatformManagerImpl.cpp", "PlatformManagerImpl.h", "SystemTimeSupport.cpp", diff --git a/examples/zap_light/main/CMakeLists.txt b/examples/zap_light/main/CMakeLists.txt index 53b7786c1..5e3c24de6 100644 --- a/examples/zap_light/main/CMakeLists.txt +++ b/examples/zap_light/main/CMakeLists.txt @@ -1,8 +1,6 @@ idf_component_register(SRC_DIRS "." "${MATTER_SDK_PATH}/src/app/util" "${MATTER_SDK_PATH}/zzz_generated/app-common/app-common/zap-generated/attributes" - # TODO Remove this from source as the zap doesn't use binding cluster - "${MATTER_SDK_PATH}/src/app/clusters/bindings" PRIV_INCLUDE_DIRS "." "${ESP_MATTER_PATH}/examples/common/utils") # We must set CHIP_ROOT to include chip_data_model.cmake diff --git a/tools/ci/certification_test_commands.json b/tools/ci/certification_test_commands.json index 632265268..bdf7512b2 100644 --- a/tools/ci/certification_test_commands.json +++ b/tools/ci/certification_test_commands.json @@ -37,7 +37,7 @@ }, "TC_CNET_4_4": { "script": "TC_CNET_4_4.py", - "args": "--timeout 300" + "args": "--timeout 300 --endpoint 0" }, "TC_DESC_2_2": { "script": "TC_DeviceBasicComposition.py", @@ -131,7 +131,7 @@ }, "TC_SC_3_6_post": { "script": "TC_SC_3_6.py", - "args": "--PICS extended_color_light_wifi_pics_code.txt --bool-arg: post_cert_test:true" + "args": "--PICS extended_color_light_wifi_pics_code.txt --bool-arg post_cert_test:true" } } } diff --git a/tools/ci/pytest_cert_helper.py b/tools/ci/pytest_cert_helper.py index 6e731bb36..04c4c1498 100644 --- a/tools/ci/pytest_cert_helper.py +++ b/tools/ci/pytest_cert_helper.py @@ -39,7 +39,7 @@ def load_test_commands(certification_tests: str): if "test_case" in test_config: test_param = f"--tests {test_config['test_case']}" - storage_path = f"--storage-path logs/{test_param}.json" + storage_path = f"--storage-path logs/{test_config['test_case']}.json" command = f"python3 {script} {common_args} {storage_path} {test_param} {args}".strip() else: storage_path = f"--storage-path logs/{test_case_name}.json" @@ -64,7 +64,20 @@ def execute_test_command(full_command, dut:Dut, retry_attempts=2): print(f"Attempt {attempt + 1} for command: {full_command}") test_out_str = subprocess.getoutput(full_command) print(f"Test output: {test_out_str}") - if "INFO:root:Final result: PASS !" in test_out_str: + results = {} + pattern = re.compile( + r"Test results:\s*" + r"Error\s+(?P\d+),\s*" + r"Executed\s+(?P\d+),\s*" + r"Failed\s+(?P\d+),\s*" + r"Passed\s+(?P\d+),\s*" + r"Requested\s+(?P\d+),\s*" + r"Skipped\s+(?P\d+)" + ) + match = pattern.search(test_out_str) + if match: + results = {k: int(v) for k, v in match.groupdict().items()} + if ("Executed" in results) and ("Passed" in results) and (results["Executed"] == results["Passed"]): print(f"Test passed on attempt {attempt + 1}.") clean_environment() time.sleep(5)