blob: 898cf77a7ac5b6a66acf42d7c6dc4dd1bce41610 [file] [log] [blame]
William A. Kennington III52575252018-02-09 15:54:56 -08001#include "watchdog_service.hpp"
2
William A. Kennington IIId5410272018-05-10 11:17:58 -07003#include <phosphor-logging/elog.hpp>
4#include <phosphor-logging/elog-errors.hpp>
5#include <phosphor-logging/log.hpp>
William A. Kennington III52575252018-02-09 15:54:56 -08006#include <sdbusplus/bus.hpp>
7#include <sdbusplus/message.hpp>
8#include <string>
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
12#include "host-ipmid/ipmid-api.h"
William A. Kennington III52575252018-02-09 15:54:56 -080013
William A. Kennington IIId5410272018-05-10 11:17:58 -070014using phosphor::logging::entry;
15using phosphor::logging::elog;
16using phosphor::logging::level;
17using phosphor::logging::log;
William A. Kennington III52575252018-02-09 15:54:56 -080018using sdbusplus::message::variant_ns::get;
19using sdbusplus::message::variant_ns::variant;
William A. Kennington IIId5410272018-05-10 11:17:58 -070020using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
William A. Kennington IIIb638de22018-02-09 16:12:53 -080021using sdbusplus::xyz::openbmc_project::State::server::convertForMessage;
22using sdbusplus::xyz::openbmc_project::State::server::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
William A. Kennington III52575252018-02-09 15:54:56 -080030WatchdogService::WatchdogService()
William A. Kennington III25bc7ac2018-03-15 11:48:41 -070031 : bus(ipmid_get_sd_bus_connection())
William A. Kennington III52575252018-02-09 15:54:56 -080032{
33}
34
William A. Kennington III4b017a92018-04-27 14:31:08 -070035void WatchdogService::resetTimeRemaining(bool enableWatchdog)
36{
37 bool wasValid = wd_service.isValid(bus);
38 auto request = wd_service.newMethodCall(
39 bus, wd_intf, "ResetTimeRemaining");
40 request.append(enableWatchdog);
41 auto response = bus.call(request);
42 if (response.is_method_error())
43 {
44 wd_service.invalidate();
45 if (wasValid)
46 {
47 // Retry the request once in case the cached service was stale
48 return resetTimeRemaining(enableWatchdog);
49 }
50 log<level::ERR>(
51 "WatchdogService: Method error resetting time remaining",
52 entry("ENABLE_WATCHDOG=%d", !!enableWatchdog));
53 elog<InternalFailure>();
54 }
55}
56
William A. Kennington III52575252018-02-09 15:54:56 -080057WatchdogService::Properties WatchdogService::getProperties()
58{
William A. Kennington IIIe1628492018-05-11 16:17:28 -070059 bool wasValid = wd_service.isValid(bus);
William A. Kennington III25bc7ac2018-03-15 11:48:41 -070060 auto request = wd_service.newMethodCall(bus, prop_intf, "GetAll");
William A. Kennington III52575252018-02-09 15:54:56 -080061 request.append(wd_intf);
62 auto response = bus.call(request);
63 if (response.is_method_error())
64 {
William A. Kennington III25bc7ac2018-03-15 11:48:41 -070065 wd_service.invalidate();
William A. Kennington IIIe1628492018-05-11 16:17:28 -070066 if (wasValid)
67 {
68 // Retry the request once in case the cached service was stale
69 return getProperties();
70 }
William A. Kennington IIId5410272018-05-10 11:17:58 -070071 log<level::ERR>("WatchdogService: Method error getting properties");
72 elog<InternalFailure>();
William A. Kennington III52575252018-02-09 15:54:56 -080073 }
74
75 std::map<std::string, variant<bool, uint64_t, std::string>> properties;
76 response.read(properties);
77 Properties wd_prop;
William A. Kennington IIIde14a022018-02-09 16:11:18 -080078 wd_prop.initialized = get<bool>(properties.at("Initialized"));
William A. Kennington III52575252018-02-09 15:54:56 -080079 wd_prop.enabled = get<bool>(properties.at("Enabled"));
William A. Kennington IIIb638de22018-02-09 16:12:53 -080080 wd_prop.expireAction = Watchdog::convertActionFromString(
81 get<std::string>(properties.at("ExpireAction")));
William A. Kennington III52575252018-02-09 15:54:56 -080082 wd_prop.interval = get<uint64_t>(properties.at("Interval"));
83 wd_prop.timeRemaining = get<uint64_t>(properties.at("TimeRemaining"));
84 return wd_prop;
85}
86
87template <typename T>
William A. Kennington III2ecf5122018-04-27 14:31:51 -070088T WatchdogService::getProperty(const std::string& key)
89{
90 bool wasValid = wd_service.isValid(bus);
91 auto request = wd_service.newMethodCall(bus, prop_intf, "Get");
92 request.append(wd_intf, key);
93 auto response = bus.call(request);
94 if (response.is_method_error())
95 {
96 wd_service.invalidate();
97 if (wasValid)
98 {
99 // Retry the request once in case the cached service was stale
100 return getProperty<T>(key);
101 }
102 log<level::ERR>("WatchdogService: Method error getting property",
103 entry("PROPERTY=%s", key.c_str()));
104 elog<InternalFailure>();
105 }
106 variant<T> value;
107 response.read(value);
108 return get<T>(value);
109}
110
111template <typename T>
William A. Kennington III52575252018-02-09 15:54:56 -0800112void WatchdogService::setProperty(const std::string& key, const T& val)
113{
William A. Kennington IIIe1628492018-05-11 16:17:28 -0700114 bool wasValid = wd_service.isValid(bus);
William A. Kennington III25bc7ac2018-03-15 11:48:41 -0700115 auto request = wd_service.newMethodCall(bus, prop_intf, "Set");
William A. Kennington III52575252018-02-09 15:54:56 -0800116 request.append(wd_intf, key, variant<T>(val));
117 auto response = bus.call(request);
118 if (response.is_method_error())
119 {
William A. Kennington III25bc7ac2018-03-15 11:48:41 -0700120 wd_service.invalidate();
William A. Kennington IIIe1628492018-05-11 16:17:28 -0700121 if (wasValid)
122 {
123 // Retry the request once in case the cached service was stale
124 return setProperty(key, val);
125 }
William A. Kennington IIId5410272018-05-10 11:17:58 -0700126 log<level::ERR>("WatchdogService: Method error setting property",
127 entry("PROPERTY=%s", key.c_str()));
128 elog<InternalFailure>();
William A. Kennington III52575252018-02-09 15:54:56 -0800129 }
130}
131
William A. Kennington III2ecf5122018-04-27 14:31:51 -0700132bool WatchdogService::getInitialized()
133{
134 return getProperty<bool>("Initialized");
135}
136
William A. Kennington IIIde14a022018-02-09 16:11:18 -0800137void WatchdogService::setInitialized(bool initialized)
138{
139 setProperty("Initialized", initialized);
140}
141
William A. Kennington III52575252018-02-09 15:54:56 -0800142void WatchdogService::setEnabled(bool enabled)
143{
144 setProperty("Enabled", enabled);
145}
146
William A. Kennington IIIb638de22018-02-09 16:12:53 -0800147void WatchdogService::setExpireAction(Action expireAction)
148{
149 setProperty("ExpireAction", convertForMessage(expireAction));
150}
151
William A. Kennington III52575252018-02-09 15:54:56 -0800152void WatchdogService::setInterval(uint64_t interval)
153{
154 setProperty("Interval", interval);
155}
156
157void WatchdogService::setTimeRemaining(uint64_t timeRemaining)
158{
159 setProperty("TimeRemaining", timeRemaining);
160}