| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 1 | #include "watchdog_service.hpp" | 
|  | 2 |  | 
| William A. Kennington III | d541027 | 2018-05-10 11:17:58 -0700 | [diff] [blame] | 3 | #include <phosphor-logging/elog.hpp> | 
|  | 4 | #include <phosphor-logging/elog-errors.hpp> | 
|  | 5 | #include <phosphor-logging/log.hpp> | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 6 | #include <sdbusplus/bus.hpp> | 
|  | 7 | #include <sdbusplus/message.hpp> | 
|  | 8 | #include <string> | 
| William A. Kennington III | d541027 | 2018-05-10 11:17:58 -0700 | [diff] [blame] | 9 | #include <xyz/openbmc_project/Common/error.hpp> | 
| William A. Kennington III | b638de2 | 2018-02-09 16:12:53 -0800 | [diff] [blame] | 10 | #include <xyz/openbmc_project/State/Watchdog/server.hpp> | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 11 |  | 
|  | 12 | #include "host-ipmid/ipmid-api.h" | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 13 |  | 
| William A. Kennington III | d541027 | 2018-05-10 11:17:58 -0700 | [diff] [blame] | 14 | using phosphor::logging::entry; | 
|  | 15 | using phosphor::logging::elog; | 
|  | 16 | using phosphor::logging::level; | 
|  | 17 | using phosphor::logging::log; | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 18 | using sdbusplus::message::variant_ns::get; | 
|  | 19 | using sdbusplus::message::variant_ns::variant; | 
| William A. Kennington III | d541027 | 2018-05-10 11:17:58 -0700 | [diff] [blame] | 20 | using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; | 
| William A. Kennington III | b638de2 | 2018-02-09 16:12:53 -0800 | [diff] [blame] | 21 | using sdbusplus::xyz::openbmc_project::State::server::convertForMessage; | 
|  | 22 | using sdbusplus::xyz::openbmc_project::State::server::Watchdog; | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 23 |  | 
|  | 24 | static constexpr char wd_path[] = "/xyz/openbmc_project/watchdog/host0"; | 
|  | 25 | static constexpr char wd_intf[] = "xyz.openbmc_project.State.Watchdog"; | 
|  | 26 | static constexpr char prop_intf[] = "org.freedesktop.DBus.Properties"; | 
|  | 27 |  | 
| William A. Kennington III | 25bc7ac | 2018-03-15 11:48:41 -0700 | [diff] [blame] | 28 | ipmi::ServiceCache WatchdogService::wd_service(wd_intf, wd_path); | 
|  | 29 |  | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 30 | WatchdogService::WatchdogService() | 
| William A. Kennington III | 25bc7ac | 2018-03-15 11:48:41 -0700 | [diff] [blame] | 31 | : bus(ipmid_get_sd_bus_connection()) | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 32 | { | 
|  | 33 | } | 
|  | 34 |  | 
| William A. Kennington III | 4b017a9 | 2018-04-27 14:31:08 -0700 | [diff] [blame] | 35 | void 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 III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 57 | WatchdogService::Properties WatchdogService::getProperties() | 
|  | 58 | { | 
| William A. Kennington III | e162849 | 2018-05-11 16:17:28 -0700 | [diff] [blame] | 59 | bool wasValid = wd_service.isValid(bus); | 
| William A. Kennington III | 25bc7ac | 2018-03-15 11:48:41 -0700 | [diff] [blame] | 60 | auto request = wd_service.newMethodCall(bus, prop_intf, "GetAll"); | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 61 | request.append(wd_intf); | 
|  | 62 | auto response = bus.call(request); | 
|  | 63 | if (response.is_method_error()) | 
|  | 64 | { | 
| William A. Kennington III | 25bc7ac | 2018-03-15 11:48:41 -0700 | [diff] [blame] | 65 | wd_service.invalidate(); | 
| William A. Kennington III | e162849 | 2018-05-11 16:17:28 -0700 | [diff] [blame] | 66 | if (wasValid) | 
|  | 67 | { | 
|  | 68 | // Retry the request once in case the cached service was stale | 
|  | 69 | return getProperties(); | 
|  | 70 | } | 
| William A. Kennington III | d541027 | 2018-05-10 11:17:58 -0700 | [diff] [blame] | 71 | log<level::ERR>("WatchdogService: Method error getting properties"); | 
|  | 72 | elog<InternalFailure>(); | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 73 | } | 
|  | 74 |  | 
|  | 75 | std::map<std::string, variant<bool, uint64_t, std::string>> properties; | 
|  | 76 | response.read(properties); | 
|  | 77 | Properties wd_prop; | 
| William A. Kennington III | de14a02 | 2018-02-09 16:11:18 -0800 | [diff] [blame] | 78 | wd_prop.initialized = get<bool>(properties.at("Initialized")); | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 79 | wd_prop.enabled = get<bool>(properties.at("Enabled")); | 
| William A. Kennington III | b638de2 | 2018-02-09 16:12:53 -0800 | [diff] [blame] | 80 | wd_prop.expireAction = Watchdog::convertActionFromString( | 
|  | 81 | get<std::string>(properties.at("ExpireAction"))); | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 82 | 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 |  | 
|  | 87 | template <typename T> | 
| William A. Kennington III | 2ecf512 | 2018-04-27 14:31:51 -0700 | [diff] [blame] | 88 | T 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 |  | 
|  | 111 | template <typename T> | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 112 | void WatchdogService::setProperty(const std::string& key, const T& val) | 
|  | 113 | { | 
| William A. Kennington III | e162849 | 2018-05-11 16:17:28 -0700 | [diff] [blame] | 114 | bool wasValid = wd_service.isValid(bus); | 
| William A. Kennington III | 25bc7ac | 2018-03-15 11:48:41 -0700 | [diff] [blame] | 115 | auto request = wd_service.newMethodCall(bus, prop_intf, "Set"); | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 116 | request.append(wd_intf, key, variant<T>(val)); | 
|  | 117 | auto response = bus.call(request); | 
|  | 118 | if (response.is_method_error()) | 
|  | 119 | { | 
| William A. Kennington III | 25bc7ac | 2018-03-15 11:48:41 -0700 | [diff] [blame] | 120 | wd_service.invalidate(); | 
| William A. Kennington III | e162849 | 2018-05-11 16:17:28 -0700 | [diff] [blame] | 121 | if (wasValid) | 
|  | 122 | { | 
|  | 123 | // Retry the request once in case the cached service was stale | 
|  | 124 | return setProperty(key, val); | 
|  | 125 | } | 
| William A. Kennington III | d541027 | 2018-05-10 11:17:58 -0700 | [diff] [blame] | 126 | log<level::ERR>("WatchdogService: Method error setting property", | 
|  | 127 | entry("PROPERTY=%s", key.c_str())); | 
|  | 128 | elog<InternalFailure>(); | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 129 | } | 
|  | 130 | } | 
|  | 131 |  | 
| William A. Kennington III | 2ecf512 | 2018-04-27 14:31:51 -0700 | [diff] [blame] | 132 | bool WatchdogService::getInitialized() | 
|  | 133 | { | 
|  | 134 | return getProperty<bool>("Initialized"); | 
|  | 135 | } | 
|  | 136 |  | 
| William A. Kennington III | de14a02 | 2018-02-09 16:11:18 -0800 | [diff] [blame] | 137 | void WatchdogService::setInitialized(bool initialized) | 
|  | 138 | { | 
|  | 139 | setProperty("Initialized", initialized); | 
|  | 140 | } | 
|  | 141 |  | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 142 | void WatchdogService::setEnabled(bool enabled) | 
|  | 143 | { | 
|  | 144 | setProperty("Enabled", enabled); | 
|  | 145 | } | 
|  | 146 |  | 
| William A. Kennington III | b638de2 | 2018-02-09 16:12:53 -0800 | [diff] [blame] | 147 | void WatchdogService::setExpireAction(Action expireAction) | 
|  | 148 | { | 
|  | 149 | setProperty("ExpireAction", convertForMessage(expireAction)); | 
|  | 150 | } | 
|  | 151 |  | 
| William A. Kennington III | 5257525 | 2018-02-09 15:54:56 -0800 | [diff] [blame] | 152 | void WatchdogService::setInterval(uint64_t interval) | 
|  | 153 | { | 
|  | 154 | setProperty("Interval", interval); | 
|  | 155 | } | 
|  | 156 |  | 
|  | 157 | void WatchdogService::setTimeRemaining(uint64_t timeRemaining) | 
|  | 158 | { | 
|  | 159 | setProperty("TimeRemaining", timeRemaining); | 
|  | 160 | } |