From c648deaf4e68b580cc0ecb43a88dde36b758b135 Mon Sep 17 00:00:00 2001 From: Sergio Soares Date: Fri, 15 Nov 2024 20:04:59 -0500 Subject: [PATCH] fan-control-server: Fix FanMode circular callback issue (#36515) Similar to what was done for Speed and Percent, this PR fixes a bug where a FanMode could result in a circular callback. For example, setting the FanMode to kAuto, could trigger this issue. --- .../fan-control-server/fan-control-server.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/app/clusters/fan-control-server/fan-control-server.cpp b/src/app/clusters/fan-control-server/fan-control-server.cpp index 7ece1a1b575a24..2c30c9c6cdfa70 100644 --- a/src/app/clusters/fan-control-server/fan-control-server.cpp +++ b/src/app/clusters/fan-control-server/fan-control-server.cpp @@ -89,6 +89,7 @@ bool gWriteFromClusterLogic = false; // Avoid circular callback calls when adjusting SpeedSetting and PercentSetting together. ScopedChangeOnly gSpeedWriteInProgress(false); ScopedChangeOnly gPercentWriteInProgress(false); +ScopedChangeOnly gFanModeWriteInProgress(false); Status SetFanModeToOff(EndpointId endpointId) { @@ -160,12 +161,16 @@ MatterFanControlClusterServerPreAttributeChangedCallback(const ConcreteAttribute switch (attributePath.mAttributeId) { case FanMode::Id: { + if (gFanModeWriteInProgress) + { + return Status::WriteIgnored; + } if (*value == to_underlying(FanModeEnum::kOn)) { FanMode::Set(attributePath.mEndpointId, FanModeEnum::kHigh); - res = Status::WriteIgnored; + return Status::WriteIgnored; } - else if (*value == to_underlying(FanModeEnum::kSmart)) + if (*value == to_underlying(FanModeEnum::kSmart)) { FanModeSequenceEnum fanModeSequence; Status status = FanModeSequence::Get(attributePath.mEndpointId, &fanModeSequence); @@ -328,6 +333,9 @@ void MatterFanControlClusterServerAttributeChangedCallback(const app::ConcreteAt Status status = FanMode::Get(attributePath.mEndpointId, &mode); VerifyOrReturn(Status::Success == status); + // Avoid circular callback calls + ScopedChange FanModeWriteInProgress(gFanModeWriteInProgress, true); + // Setting the FanMode value to Off SHALL set the values of PercentSetting, PercentCurrent, // SpeedSetting, SpeedCurrent attributes to 0 (zero). if (mode == FanModeEnum::kOff)