From a33f7bff11fe10056277b58b6e0dee69bc0b6797 Mon Sep 17 00:00:00 2001 From: "Zhibin (Ryan) Wen" Date: Thu, 26 Mar 2026 20:44:26 +0800 Subject: [PATCH] components/esp_matter_controller: use generic TLV to JSON for command responses decoding Replace hardcoded cluster-specific decoders with a generic TLV-to-JSON conversion approach in default_success_fcn. Signed-off-by: Zhibin (Ryan) Wen --- .../esp_matter/utils/jsontlv/tlv_to_json.h | 1 - .../esp_matter_controller_cluster_command.cpp | 151 +++--------------- 2 files changed, 22 insertions(+), 130 deletions(-) diff --git a/components/esp_matter/utils/jsontlv/tlv_to_json.h b/components/esp_matter/utils/jsontlv/tlv_to_json.h index 74df957ae..c69ca71fa 100644 --- a/components/esp_matter/utils/jsontlv/tlv_to_json.h +++ b/components/esp_matter/utils/jsontlv/tlv_to_json.h @@ -17,7 +17,6 @@ #include #include #include -#include namespace esp_matter { diff --git a/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.cpp b/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.cpp index 980fbda3b..b6d29c317 100644 --- a/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.cpp +++ b/components/esp_matter_controller/commands/esp_matter_controller_cluster_command.cpp @@ -1,4 +1,4 @@ -// Copyright 2022 Espressif Systems (Shanghai) PTE LTD +// Copyright 2022-2026 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. @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include +#include #include #include #include #include #include #include +#include #include #include @@ -28,117 +29,11 @@ #include #include -using namespace chip::app::Clusters; using namespace esp_matter::client; static const char *TAG = "cluster_command"; namespace esp_matter { -namespace cluster { - -template -esp_err_t decode_command_response(const ConcreteCommandPath &command_path, TLVReader *reader) -{ - ESP_RETURN_ON_FALSE(reader, ESP_ERR_INVALID_ARG, TAG, "reader cannot be NULL"); - ESP_RETURN_ON_FALSE(command_path.mClusterId == CommandResponseObjectT::GetClusterId() && - command_path.mCommandId == CommandResponseObjectT::GetCommandId(), - ESP_ERR_INVALID_ARG, TAG, "Wrong command to decode"); - DataModelLogger::LogCommand(command_path, reader); - return ESP_OK; -} - -namespace group_key_management { -namespace command { - -void decode_response(const ConcreteCommandPath &command_path, TLVReader *reader) -{ - if (command_path.mCommandId == GroupKeyManagement::Commands::KeySetReadResponse::Id) { - decode_command_response(command_path, reader); - } -} - -} // namespace command -} // namespace group_key_management - -namespace groups { -namespace command { - -void decode_response(const ConcreteCommandPath &command_path, TLVReader *reader) -{ - if (command_path.mCommandId == Groups::Commands::AddGroupResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == Groups::Commands::ViewGroupResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == Groups::Commands::RemoveGroupResponse::Id) { - decode_command_response(command_path, reader); - } -} - -} // namespace command -} // namespace groups - -namespace scenes_management { -namespace command { - -void decode_response(const ConcreteCommandPath &command_path, TLVReader *reader) -{ - if (command_path.mCommandId == ScenesManagement::Commands::AddSceneResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == ScenesManagement::Commands::ViewSceneResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == ScenesManagement::Commands::RemoveSceneResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == ScenesManagement::Commands::RemoveAllScenesResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == ScenesManagement::Commands::StoreSceneResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == ScenesManagement::Commands::GetSceneMembershipResponse::Id) { - decode_command_response(command_path, - reader); - } -} - -} // namespace command -} // namespace scenes_management - -namespace thermostat { -namespace command { - -void decode_response(const ConcreteCommandPath &command_path, TLVReader *reader) -{ - if (command_path.mCommandId == Thermostat::Commands::GetWeeklyScheduleResponse::Id) { - decode_command_response(command_path, reader); - } -} - -} // namespace command -} // namespace thermostat - -namespace door_lock { -namespace command { - -void decode_response(const ConcreteCommandPath &command_path, TLVReader *reader) -{ - if (command_path.mCommandId == DoorLock::Commands::GetWeekDayScheduleResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == DoorLock::Commands::GetYearDayScheduleResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == DoorLock::Commands::GetHolidayScheduleResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == DoorLock::Commands::GetUserResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == DoorLock::Commands::SetCredentialResponse::Id) { - decode_command_response(command_path, reader); - } else if (command_path.mCommandId == DoorLock::Commands::GetCredentialStatusResponse::Id) { - decode_command_response(command_path, reader); - } -} - -} // namespace command -} // namespace door_lock - -} // namespace cluster - namespace controller { void cluster_command::on_device_connected_fcn(void *context, ExchangeManager &exchangeMgr, @@ -169,28 +64,26 @@ void cluster_command::default_success_fcn(void *ctx, const ConcreteCommandPath & ESP_LOGI(TAG, "Some commands of specific clusters will have a response which is not NullObject, so we need to handle the " "response data for those commands. Here we print the response data."); - ESP_LOGI(TAG, - "If your command's response is not printed here, please register another success callback when creating " - "the cluster_command object to handle the response data."); - switch (command_path.mClusterId) { - case GroupKeyManagement::Id: - cluster::group_key_management::command::decode_response(command_path, response_data); - break; - case Groups::Id: - cluster::groups::command::decode_response(command_path, response_data); - break; - case ScenesManagement::Id: - cluster::scenes_management::command::decode_response(command_path, response_data); - break; - case Thermostat::Id: - cluster::thermostat::command::decode_response(command_path, response_data); - break; - case DoorLock::Id: - cluster::door_lock::command::decode_response(command_path, response_data); - break; - default: - break; + + if (!response_data) { + ESP_LOGI(TAG, "No response payload"); + return; } + + cJSON *decoded_json = nullptr; + if (tlv_to_json(*response_data, &decoded_json) != ESP_OK) { + ESP_LOGW(TAG, "Failed to convert response payload to JSON"); + cJSON_Delete(decoded_json); + return; + } + + char *formatted_response = cJSON_Print(decoded_json); + if (formatted_response) { + ESP_LOGI(TAG, "Response JSON:\n%s", formatted_response); + } + + cJSON_free(formatted_response); + cJSON_Delete(decoded_json); } void cluster_command::default_error_fcn(void *ctx, CHIP_ERROR error)