blob: 9f8c77d68c5233abbc5aa0735f05fb6314181ec4 [file] [log] [blame]
Matthew Barth279183f2021-05-25 10:19:43 -05001/**
2 * Copyright © 2021 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "config.h"
17
18#include "dbus_zone.hpp"
19
20#include "sdbusplus.hpp"
21#include "zone.hpp"
22
Matthew Barth70722372021-06-15 13:50:01 -050023#include <fmt/format.h>
24
Matthew Barth279183f2021-05-25 10:19:43 -050025#include <cereal/archives/json.hpp>
26#include <cereal/cereal.hpp>
27#include <phosphor-logging/log.hpp>
28
29#include <algorithm>
30#include <filesystem>
31#include <fstream>
32
33namespace phosphor::fan::control::json
34{
35
36using namespace phosphor::logging;
37namespace fs = std::filesystem;
38
39DBusZone::DBusZone(const Zone& zone) :
40 ThermalModeIntf(util::SDBusPlus::getBus(),
41 (fs::path{CONTROL_OBJPATH} /= zone.getName()).c_str(),
Patrick Williamsa3ed9b02022-04-05 16:24:52 -050042 ThermalModeIntf::action::defer_emit),
Matthew Barth279183f2021-05-25 10:19:43 -050043 _zone(zone)
44{}
45
46std::string DBusZone::current(std::string value)
47{
48 auto current = ThermalModeIntf::current();
49 std::transform(value.begin(), value.end(), value.begin(), toupper);
50
51 auto supported = ThermalModeIntf::supported();
52 auto isSupported =
53 std::any_of(supported.begin(), supported.end(), [&value](auto& s) {
54 std::transform(s.begin(), s.end(), s.begin(), toupper);
55 return value == s;
56 });
57
58 if (isSupported && value != current)
59 {
60 current = ThermalModeIntf::current(value);
61 if (_zone.isPersisted(thermalModeIntf, currentProp))
62 {
63 saveCurrentMode();
64 }
65 }
66
67 return current;
68}
69
70void DBusZone::restoreCurrentMode()
71{
72 auto current = ThermalModeIntf::current();
73 fs::path path{CONTROL_PERSIST_ROOT_PATH};
74 // Append this object's name and property description
75 path /= _zone.getName();
76 path /= "CurrentMode";
77 fs::create_directories(path.parent_path());
78
79 try
80 {
81 if (fs::exists(path))
82 {
83 std::ifstream ifs(path.c_str(), std::ios::in | std::ios::binary);
84 cereal::JSONInputArchive iArch(ifs);
85 iArch(current);
86 }
87 }
Patrick Williamsddb773b2021-10-06 11:24:49 -050088 catch (const std::exception& e)
Matthew Barth279183f2021-05-25 10:19:43 -050089 {
Matthew Barth70722372021-06-15 13:50:01 -050090 // Include possible exception when removing file, otherwise ec = 0
91 std::error_code ec;
92 fs::remove(path, ec);
93 log<level::ERR>(
94 fmt::format("Unable to restore persisted `Current` thermal mode "
95 "property ({}, ec: {})",
96 e.what(), ec.value())
97 .c_str());
Matthew Barth279183f2021-05-25 10:19:43 -050098 current = ThermalModeIntf::current();
99 }
100
101 this->current(current);
102}
103
104void DBusZone::saveCurrentMode()
105{
106 fs::path path{CONTROL_PERSIST_ROOT_PATH};
107 // Append this object's name and property description
108 path /= _zone.getName();
109 path /= "CurrentMode";
110 std::ofstream ofs(path.c_str(), std::ios::binary);
111 cereal::JSONOutputArchive oArch(ofs);
112 oArch(ThermalModeIntf::current());
113}
114
115} // namespace phosphor::fan::control::json