blob: b67b5c759e3725181be960d4977d30acae8dbbb9 [file] [log] [blame]
William A. Kennington III52575252018-02-09 15:54:56 -08001#include "watchdog_service.hpp"
2
Vernon Mauerye08fbff2019-04-03 09:19:34 -07003#include <ipmid/api.hpp>
William A. Kennington IIId5410272018-05-10 11:17:58 -07004#include <phosphor-logging/elog-errors.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -07005#include <phosphor-logging/elog.hpp>
George Liu05e93872024-07-17 14:48:14 +08006#include <phosphor-logging/lg2.hpp>
William A. Kennington III52575252018-02-09 15:54:56 -08007#include <sdbusplus/bus.hpp>
8#include <sdbusplus/message.hpp>
William A. Kennington IIId5410272018-05-10 11:17:58 -07009#include <xyz/openbmc_project/Common/error.hpp>
William A. Kennington IIIb638de22018-02-09 16:12:53 -080010#include <xyz/openbmc_project/State/Watchdog/server.hpp>
William A. Kennington III52575252018-02-09 15:54:56 -080011
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050012#include <exception>
13#include <stdexcept>
14#include <string>
15
William A. Kennington IIId5410272018-05-10 11:17:58 -070016using phosphor::logging::elog;
Patrick Venture0b02be92018-08-31 11:55:55 -070017using phosphor::logging::entry;
William A. Kennington IIId5410272018-05-10 11:17:58 -070018using phosphor::logging::level;
19using phosphor::logging::log;
Willy Tu523e2d12023-09-05 11:36:48 -070020using sdbusplus::common::xyz::openbmc_project::state::convertForMessage;
21using sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
22using sdbusplus::server::xyz::openbmc_project::state::Watchdog;
William A. Kennington III52575252018-02-09 15:54:56 -080023
24static constexpr char wd_path[] = "/xyz/openbmc_project/watchdog/host0";
25static constexpr char wd_intf[] = "xyz.openbmc_project.State.Watchdog";
26static constexpr char prop_intf[] = "org.freedesktop.DBus.Properties";
27
William A. Kennington III25bc7ac2018-03-15 11:48:41 -070028ipmi::ServiceCache WatchdogService::wd_service(wd_intf, wd_path);
29
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050030WatchdogService::WatchdogService() : bus(ipmid_get_sd_bus_connection()) {}
William A. Kennington III52575252018-02-09 15:54:56 -080031
William A. Kennington III4b017a92018-04-27 14:31:08 -070032void WatchdogService::resetTimeRemaining(bool enableWatchdog)
33{
34 bool wasValid = wd_service.isValid(bus);
Patrick Venture0b02be92018-08-31 11:55:55 -070035 auto request = wd_service.newMethodCall(bus, wd_intf, "ResetTimeRemaining");
William A. Kennington III4b017a92018-04-27 14:31:08 -070036 request.append(enableWatchdog);
George Liu3e3cc352023-07-26 15:59:31 +080037 try
38 {
39 auto response = bus.call(request);
40 }
41 catch (const std::exception& e)
William A. Kennington III4b017a92018-04-27 14:31:08 -070042 {
43 wd_service.invalidate();
44 if (wasValid)
45 {
46 // Retry the request once in case the cached service was stale
47 return resetTimeRemaining(enableWatchdog);
48 }
George Liu05e93872024-07-17 14:48:14 +080049 lg2::error("WatchdogService: Method error resetting time remaining, "
50 "ENABLE_WATCHDOG: {ENABLE_WATCHDOG}, ERROR: {ERROR}",
51 "ENABLE_WATCHDOG", enableWatchdog, "ERROR", e);
William A. Kennington III4b017a92018-04-27 14:31:08 -070052 elog<InternalFailure>();
53 }
54}
55
William A. Kennington III52575252018-02-09 15:54:56 -080056WatchdogService::Properties WatchdogService::getProperties()
57{
William A. Kennington IIIe1628492018-05-11 16:17:28 -070058 bool wasValid = wd_service.isValid(bus);
William A. Kennington III25bc7ac2018-03-15 11:48:41 -070059 auto request = wd_service.newMethodCall(bus, prop_intf, "GetAll");
William A. Kennington III52575252018-02-09 15:54:56 -080060 request.append(wd_intf);
George Liu3e3cc352023-07-26 15:59:31 +080061
62 std::map<std::string, std::variant<bool, uint64_t, std::string>> properties;
63 try
64 {
65 auto response = bus.call(request);
66 response.read(properties);
67 }
68 catch (const std::exception& e)
William A. Kennington III52575252018-02-09 15:54:56 -080069 {
William A. Kennington III25bc7ac2018-03-15 11:48:41 -070070 wd_service.invalidate();
William A. Kennington IIIe1628492018-05-11 16:17:28 -070071 if (wasValid)
72 {
73 // Retry the request once in case the cached service was stale
74 return getProperties();
75 }
George Liu05e93872024-07-17 14:48:14 +080076 lg2::error("WatchdogService: Method error getting properties: {ERROR}",
77 "ERROR", e);
William A. Kennington IIId5410272018-05-10 11:17:58 -070078 elog<InternalFailure>();
William A. Kennington III52575252018-02-09 15:54:56 -080079 }
George Liu3e3cc352023-07-26 15:59:31 +080080
William A. Kennington III1469f8a2018-05-15 14:40:59 -070081 try
82 {
William A. Kennington III1469f8a2018-05-15 14:40:59 -070083 Properties wd_prop;
Vernon Maueryf442e112019-04-09 11:44:36 -070084 wd_prop.initialized = std::get<bool>(properties.at("Initialized"));
85 wd_prop.enabled = std::get<bool>(properties.at("Enabled"));
William A. Kennington III1469f8a2018-05-15 14:40:59 -070086 wd_prop.expireAction = Watchdog::convertActionFromString(
Vernon Maueryf442e112019-04-09 11:44:36 -070087 std::get<std::string>(properties.at("ExpireAction")));
Yong Li118907e2019-01-11 17:36:17 +080088 wd_prop.timerUse = Watchdog::convertTimerUseFromString(
Vernon Maueryf442e112019-04-09 11:44:36 -070089 std::get<std::string>(properties.at("CurrentTimerUse")));
Yong Li4dd71af2019-09-29 14:18:07 +080090 wd_prop.expiredTimerUse = Watchdog::convertTimerUseFromString(
91 std::get<std::string>(properties.at("ExpiredTimerUse")));
Yong Li118907e2019-01-11 17:36:17 +080092
Vernon Maueryf442e112019-04-09 11:44:36 -070093 wd_prop.interval = std::get<uint64_t>(properties.at("Interval"));
94 wd_prop.timeRemaining =
95 std::get<uint64_t>(properties.at("TimeRemaining"));
William A. Kennington III1469f8a2018-05-15 14:40:59 -070096 return wd_prop;
97 }
98 catch (const std::exception& e)
99 {
George Liu05e93872024-07-17 14:48:14 +0800100 lg2::error("WatchdogService: Decode error in get properties: {ERROR}",
101 "ERROR", e);
William A. Kennington III1469f8a2018-05-15 14:40:59 -0700102 elog<InternalFailure>();
103 }
William A. Kennington III52575252018-02-09 15:54:56 -0800104
William A. Kennington III1469f8a2018-05-15 14:40:59 -0700105 // Needed instead of elog<InternalFailure>() since the compiler can't
106 // deduce the that elog<>() always throws
107 throw std::runtime_error(
Patrick Venture0b02be92018-08-31 11:55:55 -0700108 "WatchdogService: Should not reach end of getProperties");
William A. Kennington III52575252018-02-09 15:54:56 -0800109}
110
111template <typename T>
William A. Kennington III2ecf5122018-04-27 14:31:51 -0700112T WatchdogService::getProperty(const std::string& key)
113{
114 bool wasValid = wd_service.isValid(bus);
115 auto request = wd_service.newMethodCall(bus, prop_intf, "Get");
116 request.append(wd_intf, key);
George Liu3e3cc352023-07-26 15:59:31 +0800117 try
118 {
119 auto response = bus.call(request);
120 std::variant<T> value;
121 response.read(value);
122 return std::get<T>(value);
123 }
124 catch (const std::exception& e)
William A. Kennington III2ecf5122018-04-27 14:31:51 -0700125 {
126 wd_service.invalidate();
127 if (wasValid)
128 {
129 // Retry the request once in case the cached service was stale
130 return getProperty<T>(key);
131 }
George Liu05e93872024-07-17 14:48:14 +0800132 lg2::error("WatchdogService: Method error getting {PROPERTY}: {ERROR}",
133 "PROPERTY", key, "ERROR", e);
William A. Kennington III1469f8a2018-05-15 14:40:59 -0700134 elog<InternalFailure>();
135 }
136
137 // Needed instead of elog<InternalFailure>() since the compiler can't
138 // deduce the that elog<>() always throws
139 throw std::runtime_error(
Patrick Venture0b02be92018-08-31 11:55:55 -0700140 "WatchdogService: Should not reach end of getProperty");
William A. Kennington III2ecf5122018-04-27 14:31:51 -0700141}
142
143template <typename T>
William A. Kennington III52575252018-02-09 15:54:56 -0800144void WatchdogService::setProperty(const std::string& key, const T& val)
145{
William A. Kennington IIIe1628492018-05-11 16:17:28 -0700146 bool wasValid = wd_service.isValid(bus);
William A. Kennington III25bc7ac2018-03-15 11:48:41 -0700147 auto request = wd_service.newMethodCall(bus, prop_intf, "Set");
Vernon Maueryf442e112019-04-09 11:44:36 -0700148 request.append(wd_intf, key, std::variant<T>(val));
George Liu3e3cc352023-07-26 15:59:31 +0800149 try
150 {
151 auto response = bus.call(request);
152 }
153 catch (const std::exception& e)
William A. Kennington III52575252018-02-09 15:54:56 -0800154 {
William A. Kennington III25bc7ac2018-03-15 11:48:41 -0700155 wd_service.invalidate();
William A. Kennington IIIe1628492018-05-11 16:17:28 -0700156 if (wasValid)
157 {
158 // Retry the request once in case the cached service was stale
Chen,Yugang0e862fa2019-09-06 11:03:05 +0800159 setProperty(key, val);
160 return;
William A. Kennington IIIe1628492018-05-11 16:17:28 -0700161 }
George Liu05e93872024-07-17 14:48:14 +0800162 lg2::error("WatchdogService: Method error setting {PROPERTY}: {ERROR}",
163 "PROPERTY", key, "ERROR", e);
William A. Kennington IIId5410272018-05-10 11:17:58 -0700164 elog<InternalFailure>();
William A. Kennington III52575252018-02-09 15:54:56 -0800165 }
166}
167
William A. Kennington III2ecf5122018-04-27 14:31:51 -0700168bool WatchdogService::getInitialized()
169{
170 return getProperty<bool>("Initialized");
171}
172
William A. Kennington IIIde14a022018-02-09 16:11:18 -0800173void WatchdogService::setInitialized(bool initialized)
174{
175 setProperty("Initialized", initialized);
176}
177
William A. Kennington III52575252018-02-09 15:54:56 -0800178void WatchdogService::setEnabled(bool enabled)
179{
180 setProperty("Enabled", enabled);
181}
182
Tim Chao65362f42023-11-14 14:47:25 +0800183void WatchdogService::setLogTimeout(bool LogTimeout)
184{
185 setProperty("LogTimeout", LogTimeout);
186}
187
William A. Kennington IIIb638de22018-02-09 16:12:53 -0800188void WatchdogService::setExpireAction(Action expireAction)
189{
190 setProperty("ExpireAction", convertForMessage(expireAction));
191}
192
Yong Li118907e2019-01-11 17:36:17 +0800193void WatchdogService::setTimerUse(TimerUse timerUse)
194{
195 setProperty("CurrentTimerUse", convertForMessage(timerUse));
196}
197
Deepak Kumar Sahucfae9482019-05-20 14:58:58 +0000198void WatchdogService::setExpiredTimerUse(TimerUse timerUse)
199{
200 setProperty("ExpiredTimerUse", convertForMessage(timerUse));
201}
202
William A. Kennington III52575252018-02-09 15:54:56 -0800203void WatchdogService::setInterval(uint64_t interval)
204{
205 setProperty("Interval", interval);
206}