From e5b614654c16a4d1913bb3c7ef90a5dcf8c5dac0 Mon Sep 17 00:00:00 2001 From: Rohit Date: Wed, 16 Jul 2025 14:39:07 +0530 Subject: [PATCH] components/esp-matter: Fix multiple cluster instance creation in microwave oven device type. Fixes https://github.com/espressif/esp-matter/issues/1486. --- .../esp_matter_delegate_callbacks.cpp | 60 +++++++++++++++---- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/components/esp_matter/esp_matter_delegate_callbacks.cpp b/components/esp_matter/esp_matter_delegate_callbacks.cpp index 459196f6c..b2b27b355 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.cpp +++ b/components/esp_matter/esp_matter_delegate_callbacks.cpp @@ -46,11 +46,15 @@ #include #include #include +#include using namespace chip::app::Clusters; namespace esp_matter { namespace cluster { +static std::unordered_map s_microwave_oven_mode_instances; +static std::unordered_map s_operational_state_instances; + static uint32_t get_feature_map_value(uint16_t endpoint_id, uint32_t cluster_id) { uint32_t attribute_id = Globals::Attributes::FeatureMap::Id; @@ -110,7 +114,19 @@ void EnergyEvseModeDelegateInitCB(void *delegate, uint16_t endpoint_id) void MicrowaveOvenModeDelegateInitCB(void *delegate, uint16_t endpoint_id) { - InitModeDelegate(delegate, endpoint_id, MicrowaveOvenMode::Id); + VerifyOrReturn(delegate != nullptr); + ModeBase::Delegate *mode_delegate = static_cast(delegate); + ModeBase::Instance * modeInstance = nullptr; + // Create new instance of MicrowaveOvenMode if not found in the map, otherwise use existing instance. + if(s_microwave_oven_mode_instances.find(endpoint_id) == s_microwave_oven_mode_instances.end()) + { + uint32_t feature_map = get_feature_map_value(endpoint_id, MicrowaveOvenMode::Id); + modeInstance = new ModeBase::Instance(mode_delegate, endpoint_id, MicrowaveOvenMode::Id, feature_map); + s_microwave_oven_mode_instances[endpoint_id] = modeInstance; + } else { + modeInstance = s_microwave_oven_mode_instances[endpoint_id]; + } + modeInstance->Init(); } void DeviceEnergyManagementModeDelegateInitCB(void *delegate, uint16_t endpoint_id) @@ -137,17 +153,32 @@ void MicrowaveOvenControlDelegateInitCB(void *delegate, uint16_t endpoint_id) cluster = cluster::get(endpoint_id, OperationalState::Id); OperationalState::Delegate *operational_state_delegate = static_cast(get_delegate_impl(cluster)); VerifyOrReturn(delegate != nullptr && microwave_oven_mode_delegate != nullptr && operational_state_delegate != nullptr); - // Create instances of clusters. - static ModeBase::Instance * microwaveOvenModeInstance = nullptr; - static OperationalState::Instance * operationalStateInstance = nullptr; + ModeBase::Instance* microwaveOvenModeInstance = nullptr; + OperationalState::Instance* operationalStateInstance = nullptr; + + // Create new instance of MicrowaveOvenMode if not found in the map, otherwise use existing instance. + if(s_microwave_oven_mode_instances.find(endpoint_id) == s_microwave_oven_mode_instances.end()) + { + uint32_t feature_map = get_feature_map_value(endpoint_id, MicrowaveOvenMode::Id); + microwaveOvenModeInstance = new ModeBase::Instance(microwave_oven_mode_delegate, endpoint_id, MicrowaveOvenMode::Id, feature_map); + s_microwave_oven_mode_instances[endpoint_id] = microwaveOvenModeInstance; + } else { + microwaveOvenModeInstance = s_microwave_oven_mode_instances[endpoint_id]; + } + + // Create new instance of OperationalState if not found in the map, otherwise use existing instance. + if(s_operational_state_instances.find(endpoint_id) == s_operational_state_instances.end()) + { + operationalStateInstance = new OperationalState::Instance(operational_state_delegate, endpoint_id); + s_operational_state_instances[endpoint_id] = operationalStateInstance; + } else { + operationalStateInstance = s_operational_state_instances[endpoint_id]; + } + + // Create MicrowaveOvenControl instance static MicrowaveOvenControl::Instance * microwaveOvenControlInstance = nullptr; MicrowaveOvenControl::Delegate *microwave_oven_control_delegate = static_cast(delegate); - uint32_t feature_map = get_feature_map_value(endpoint_id, MicrowaveOvenMode::Id); - - microwaveOvenModeInstance = new ModeBase::Instance(microwave_oven_mode_delegate, endpoint_id, MicrowaveOvenMode::Id, feature_map); - operationalStateInstance = new OperationalState::Instance(operational_state_delegate, endpoint_id); - - feature_map = get_feature_map_value(endpoint_id, MicrowaveOvenControl::Id); + uint32_t feature_map = get_feature_map_value(endpoint_id, MicrowaveOvenControl::Id); microwaveOvenControlInstance = new MicrowaveOvenControl::Instance(microwave_oven_control_delegate, endpoint_id, MicrowaveOvenControl::Id, feature_map, *operationalStateInstance, *microwaveOvenModeInstance); microwaveOvenControlInstance->Init(); @@ -158,7 +189,14 @@ void OperationalStateDelegateInitCB(void *delegate, uint16_t endpoint_id) VerifyOrReturn(delegate != nullptr); static OperationalState::Instance * operationalStateInstance = nullptr; OperationalState::Delegate *operational_state_delegate = static_cast(delegate); - operationalStateInstance = new OperationalState::Instance(operational_state_delegate, endpoint_id); + // Create new instance of OperationalState if not found in the map, otherwise use existing instance. + if(s_operational_state_instances.find(endpoint_id) == s_operational_state_instances.end()) + { + operationalStateInstance = new OperationalState::Instance(operational_state_delegate, endpoint_id); + s_operational_state_instances[endpoint_id] = operationalStateInstance; + } else { + operationalStateInstance = s_operational_state_instances[endpoint_id]; + } operationalStateInstance->Init(); }