From 87678ff5cf4c46bfd1f39db1fc6826732b39792e Mon Sep 17 00:00:00 2001 From: InfiniteYuan Date: Wed, 7 Jun 2023 20:09:20 +0800 Subject: [PATCH] feature: add software_diagnostics and diagnostic_logs cluster --- .../esp_matter/esp_matter_attribute.cpp | 13 ++ components/esp_matter/esp_matter_attribute.h | 6 + components/esp_matter/esp_matter_cluster.cpp | 166 +++++++++++++++++- components/esp_matter/esp_matter_cluster.h | 18 ++ components/esp_matter/esp_matter_command.cpp | 40 +++++ components/esp_matter/esp_matter_command.h | 13 ++ components/esp_matter/esp_matter_feature.cpp | 35 +++- components/esp_matter/esp_matter_feature.h | 18 ++ 8 files changed, 306 insertions(+), 3 deletions(-) diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 0911d6092..29047952e 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -416,6 +416,19 @@ attribute_t *create_test_event_triggers_enabled(cluster_t *cluster, bool value) } /* attribute */ } /* general_diagnostics */ + +namespace software_diagnostics { +namespace attribute { + +attribute_t *create_current_heap_high_watermark(cluster_t *cluster, uint64_t value) +{ + return esp_matter::attribute::create(cluster, SoftwareDiagnostics::Attributes::CurrentHeapHighWatermark::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value)); +} + +} /* attribute */ +} /* software_diagnostics */ + namespace administrator_commissioning { namespace attribute { diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 9834f1094..e7e916567 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -135,6 +135,12 @@ attribute_t *create_test_event_triggers_enabled(cluster_t *cluster, bool value); } /* attribute */ } /* general_diagnostics */ +namespace software_diagnostics { +namespace attribute { +attribute_t *create_current_heap_high_watermark(cluster_t *cluster, uint64_t value); +} /* attribute */ +} /* software_diagnostics */ + namespace administrator_commissioning { namespace attribute { attribute_t *create_window_status(cluster_t *cluster, uint8_t value); diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 2602b16e1..fcb26e546 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -103,7 +103,7 @@ const int function_flags = CLUSTER_FLAG_NONE; cluster_t *create(endpoint_t *endpoint, uint8_t flags) { - cluster_t *cluster = cluster::create(endpoint, Descriptor::Id, flags); + cluster_t *cluster = cluster::create(endpoint, Actions::Id, flags); if (!cluster) { ESP_LOGE(TAG, "Could not create cluster"); return NULL; @@ -1561,7 +1561,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) namespace time_format_localization { const function_generic_t function_list[] = { (function_generic_t)emberAfTimeFormatLocalizationClusterServerInitCallback, - (function_generic_t)MatterLocalizationConfigurationClusterServerPreAttributeChangedCallback}; + (function_generic_t)MatterTimeFormatLocalizationClusterServerPreAttributeChangedCallback}; const int function_flags = CLUSTER_FLAG_INIT_FUNCTION | CLUSTER_FLAG_PRE_ATTRIBUTE_CHANGED_FUNCTION; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features) @@ -1806,6 +1806,168 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ } } /* mode_select */ +namespace diagnostic_logs { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) +{ + cluster_t *cluster = cluster::create(endpoint, DiagnosticLogs::Id, flags); + + if (flags & CLUSTER_FLAG_SERVER) { + set_plugin_server_init_callback(cluster, MatterDiagnosticLogsPluginServerInitCallback); + add_function_list(cluster, function_list, function_flags); + } + if (flags & CLUSTER_FLAG_CLIENT) { + create_default_binding_cluster(endpoint); + } + + if (flags & CLUSTER_FLAG_SERVER) { + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + /* commands */ + command::create_retrieve_logs_request(cluster); + command::create_retrieve_logs_response(cluster); + + return cluster; +} +} /* diagnostic_logs */ + +namespace software_diagnostics { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features) +{ + cluster_t *cluster = cluster::create(endpoint, SoftwareDiagnostics::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + set_plugin_server_init_callback(cluster, MatterSoftwareDiagnosticsPluginServerInitCallback); + add_function_list(cluster, function_list, function_flags); + } + if (flags & CLUSTER_FLAG_SERVER) { + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + /* Features */ + if (features & feature::watermarks::get_id()) { + feature::watermarks::add(cluster); + } + + return cluster; +} +} /* software_diagnostics */ + +// namespace binary_input_basic { +// // ToDo +// } /* binary_input_basic */ + +// namespace pulse_width_modulation { +// // ToDo +// } /* pulse_width_modulation */ + +// namespace unit_localization { +// // ToDo +// } /* unit_localization */ + +// namespace powersource_configuration { +// // ToDo +// } /* powersource_configuration */ + +// namespace powersource { +// // ToDo +// } /* powersource */ + +// namespace ethernet_network_diagnostics { +// // ToDo +// } /* ethernet_network_diagnostics */ + +// namespace proxy_configuration { +// // ToDo +// } /* proxy_configuration */ + +// namespace proxy_discovery { +// // ToDo +// } /* proxy_discovery */ + +// namespace proxy_valid { +// // ToDo +// } /* proxy_valid */ + +// namespace mode_select { +// // ToDo +// } /* mode_select */ + +// namespace barrier_control { +// // ToDo +// } /* barrier_control */ + +// namespace thermostat_userinterface_configuration { +// // ToDo +// } /* thermostat_userinterface_configuration */ + +// namespace ballast_configuration { +// // ToDo +// } /* ballast_configuration */ + +// namespace wakeonlan { +// // ToDo +// } /* wakeonlan */ + +// namespace channel { +// // ToDo +// } /* channel */ + +// namespace target_navigator { +// // ToDo +// } /* target_navigator */ + +// namespace media_playback { +// // ToDo +// } /* media_playback */ + +// namespace media_input { +// // ToDo +// } /* media_input */ + +// namespace lowpower { +// // ToDo +// } /* lowpower */ + +// namespace keypad_input { +// // ToDo +// } /* keypad_input */ + +// namespace content_launcher { +// // ToDo +// } /* content_launcher */ + +// namespace audio_output { +// // ToDo +// } /* audio_output */ + #endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 418e5792d..38c2f6955 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -111,6 +111,15 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* network_commissioning */ +namespace diagnostic_logs { +typedef struct config { + uint16_t cluster_revision; + config() : cluster_revision(1) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* diagnostic_logs */ + namespace general_diagnostics { typedef struct config { uint16_t cluster_revision; @@ -120,6 +129,15 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* general_diagnostics */ +namespace software_diagnostics { +typedef struct config { + uint16_t cluster_revision; + config() : cluster_revision(1) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); +} /* software_diagnostics */ + namespace administrator_commissioning { typedef struct config { uint16_t cluster_revision; diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index ead116402..acf814f8f 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -898,6 +898,17 @@ static esp_err_t esp_matter_command_callback_wifi_reset_counts(const ConcreteCom 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_test_event_trigger(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr) { @@ -1232,6 +1243,23 @@ command_t *create_reset_counts(cluster_t *cluster) } /* command */ } /* diagnostics_network_wifi */ +namespace diagnostic_logs { +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); +} + +command_t *create_retrieve_logs_response(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DiagnosticLogs::Commands::RetrieveLogsResponse::Id, + COMMAND_FLAG_GENERATED, NULL); +} + +} /* command */ +} /* diagnostic_logs */ namespace general_diagnostics { namespace command { @@ -1245,6 +1273,18 @@ command_t *create_test_event_trigger(cluster_t *cluster) } /* command */ } /* general_diagnostics */ +namespace software_diagnostics { +namespace command { + +command_t *create_reset_watermarks(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, SoftwareDiagnostics::Commands::ResetWatermarks::Id, + COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* software_diagnostics */ + namespace group_key_management { namespace command { diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 162c6dabd..1e86d110c 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -54,12 +54,25 @@ command_t *create_reset_counts(cluster_t *cluster); } /* command */ } /* diagnostics_network_wifi */ +namespace diagnostic_logs { +namespace command { +command_t *create_retrieve_logs_request(cluster_t *cluster); +command_t *create_retrieve_logs_response(cluster_t *cluster); +} /* command */ +} /* diagnostic_logs */ + namespace general_diagnostics { namespace command { command_t *create_test_event_trigger(cluster_t *cluster); } /* command */ } /* general_diagnostics */ +namespace software_diagnostics { +namespace command { +command_t *create_reset_watermarks(cluster_t *cluster); +} /* command */ +} /* software_diagnostics */ + namespace group_key_management { namespace command { command_t *create_key_set_write(cluster_t *cluster); diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 9a77e4f04..21b58ec3c 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -1010,10 +1010,43 @@ esp_err_t add(cluster_t *cluster, config_t *config) return ESP_OK; } - } /* on_off */ } /* feature */ } /* mode_select */ + +namespace software_diagnostics { +namespace feature { + +namespace watermarks { + +uint32_t get_id() +{ + // enum class for SoftwareDiagnosticsFeature is not present in the upstream code. + // Return the code according to the SPEC + return 0x01; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_current_heap_high_watermark(cluster, 0); + + /* commands */ + command::create_reset_watermarks(cluster); + + return ESP_OK; +} +} /* watermarks */ + +} /* feature */ +} /* software_diagnostics */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 37dc5b16c..06185b671 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -440,5 +440,23 @@ esp_err_t add(cluster_t *cluster, config_t *config); } /* feature */ } /* mode_select */ +namespace software_diagnostics { +namespace feature { + +namespace watermarks { + +typedef struct config { + uint64_t current_heap_high_watermark; + config() : current_heap_high_watermark(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* watermarks */ + +} /* feature */ +} /* software_diagnostics */ + } /* cluster */ } /* esp_matter */