From 7ebc1c04cd5f74b6b17a6e47f37defb161daab00 Mon Sep 17 00:00:00 2001 From: Anton Usmansky Date: Wed, 3 Jul 2024 13:22:39 +0300 Subject: [PATCH] feat: restore onOffValue after reboot during OTA applying --- .../clusters/on-off-server/on-off-server.cpp | 77 ++++++++++++------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/src/app/clusters/on-off-server/on-off-server.cpp b/src/app/clusters/on-off-server/on-off-server.cpp index c7e64cd7afc161..3eca4871ca33c9 100644 --- a/src/app/clusters/on-off-server/on-off-server.cpp +++ b/src/app/clusters/on-off-server/on-off-server.cpp @@ -45,6 +45,7 @@ #endif // MATTER_DM_PLUGIN_MODE_BASE #include +#include #include using namespace chip; @@ -52,6 +53,8 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::OnOff; using chip::Protocols::InteractionModel::Status; +using BootReasonType = GeneralDiagnostics::BootReasonEnum; + namespace { #ifdef MATTER_DM_PLUGIN_MODE_BASE @@ -89,6 +92,21 @@ void UpdateModeBaseCurrentModeToOnMode(EndpointId endpoint) #endif // MATTER_DM_PLUGIN_MODE_BASE +BootReasonType GetBootReason() { + BootReasonType bootReason = BootReasonType::kUnspecified; + + CHIP_ERROR error = DeviceLayer::GetDiagnosticDataProvider().GetBootReason(bootReason); + if (error != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Unable to retrieve boot reason: %" CHIP_ERROR_FORMAT, error.Format()); + bootReason = BootReasonType::kUnspecified; + } + + ChipLogProgress(Zcl, "Boot reason: %u", to_underlying(bootReason)); + + return bootReason; +} + } // namespace #ifdef MATTER_DM_PLUGIN_LEVEL_CONTROL @@ -541,35 +559,40 @@ Status OnOffServer::getOnOffValueForStartUp(chip::EndpointId endpoint, bool & on { app::DataModel::Nullable startUpOnOff; Status status = Attributes::StartUpOnOff::Get(endpoint, startUpOnOff); - if (status == Status::Success) + if (status != Status::Success) { - // Initialise updated value to 0 - bool updatedOnOff = false; - status = Attributes::OnOff::Get(endpoint, &updatedOnOff); - if (status == Status::Success) - { - if (!startUpOnOff.IsNull()) - { - switch (startUpOnOff.Value()) - { - case OnOff::StartUpOnOffEnum::kOff: - updatedOnOff = false; // Off - break; - case OnOff::StartUpOnOffEnum::kOn: - updatedOnOff = true; // On - break; - case OnOff::StartUpOnOffEnum::kToggle: - updatedOnOff = !updatedOnOff; - break; - default: - // All other values 0x03- 0xFE are reserved - no action. - break; - } - } - onOffValueForStartUp = updatedOnOff; - } + return status; } - return status; + + bool currentOnOff = false; + status = Attributes::OnOff::Get(endpoint, ¤tOnOff); + if (status != Status::Success) { + return status; + } + + if (startUpOnOff.IsNull() || GetBootReason() == BootReasonType::kSoftwareUpdateCompleted) + { + onOffValueForStartUp = currentOnOff; + return Status::Success; + } + + switch (startUpOnOff.Value()) + { + case OnOff::StartUpOnOffEnum::kOff: + onOffValueForStartUp = false; // Off + break; + case OnOff::StartUpOnOffEnum::kOn: + onOffValueForStartUp = true; // On + break; + case OnOff::StartUpOnOffEnum::kToggle: + onOffValueForStartUp = !currentOnOff; + break; + default: + // All other values 0x03- 0xFE are reserved - no action. + break; + } + + return Status::Success; } bool OnOffServer::offCommand(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath)