summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2018-02-09 15:28:46 -0800
committerWilliam A. Kennington III <wak@google.com>2018-02-21 23:54:59 +0000
commit73f44518bdafd438f800d31d47ee9176d42cc83f (patch)
tree71e66cc60a1c128efc5e47e645c97139d061a247 /app
parentb638de22154aa4cae788d9117d2507394388f839 (diff)
downloadphosphor-host-ipmid-73f44518bdafd438f800d31d47ee9176d42cc83f.zip
phosphor-host-ipmid-73f44518bdafd438f800d31d47ee9176d42cc83f.tar.gz
watchdog: Implements the Watchdog Get Command
Change-Id: I2ba9fd0eeba4e828cafd1bcf6fe30e2322eaf99e Signed-off-by: William A. Kennington III <wak@google.com>
Diffstat (limited to 'app')
-rw-r--r--app/watchdog.cpp98
-rw-r--r--app/watchdog.hpp18
2 files changed, 116 insertions, 0 deletions
diff --git a/app/watchdog.cpp b/app/watchdog.cpp
index 84d80b9..7b1d987 100644
--- a/app/watchdog.cpp
+++ b/app/watchdog.cpp
@@ -167,3 +167,101 @@ ipmi_ret_t ipmi_app_watchdog_set(
return IPMI_CC_UNSPECIFIED_ERROR;
}
}
+
+/** @brief Converts a DBUS Watchdog Action to IPMI defined action
+ * @param[in] wd_action The DBUS Watchdog Action
+ * @return The IpmiAction that the wd_action maps to
+ */
+IpmiAction wdActionToIpmiAction(WatchdogService::Action wd_action)
+{
+ switch(wd_action)
+ {
+ case WatchdogService::Action::None:
+ {
+ return IpmiAction::None;
+ }
+ case WatchdogService::Action::HardReset:
+ {
+ return IpmiAction::HardReset;
+ }
+ case WatchdogService::Action::PowerOff:
+ {
+ return IpmiAction::PowerOff;
+ }
+ case WatchdogService::Action::PowerCycle:
+ {
+ return IpmiAction::PowerCycle;
+ }
+ default:
+ {
+ // We have no method via IPMI to signal that the action is unknown
+ // or unmappable in some way.
+ // Just ignore the error and return NONE so the host can reconcile.
+ return IpmiAction::None;
+ }
+ }
+}
+
+struct wd_get_res {
+ uint8_t timer_use;
+ uint8_t timer_action;
+ uint8_t pretimeout;
+ uint8_t expire_flags;
+ uint16_t initial_countdown; // Little Endian (deciseconds)
+ uint16_t present_countdown; // Little Endian (deciseconds)
+} __attribute__ ((packed));
+static_assert(sizeof(wd_get_res) == 8, "wd_get_res has invalid size.");
+static_assert(sizeof(wd_get_res) <= MAX_IPMI_BUFFER,
+ "wd_get_res can't fit in response buffer.");
+
+static constexpr uint8_t wd_dont_log = 0x1 << 7;
+static constexpr uint8_t wd_running = 0x1 << 6;
+
+ipmi_ret_t ipmi_app_watchdog_get(
+ ipmi_netfn_t netfn,
+ ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+ ipmi_data_len_t data_len,
+ ipmi_context_t context)
+{
+ // Assume we will fail and send no data outside the return code
+ *data_len = 0;
+
+ try
+ {
+ WatchdogService wd_service;
+ WatchdogService::Properties wd_prop = wd_service.getProperties();
+
+ // Build and return the response
+ wd_get_res res;
+ res.timer_use = wd_dont_log;
+ res.timer_action = static_cast<uint8_t>(
+ wdActionToIpmiAction(wd_prop.expireAction));
+ if (wd_prop.enabled)
+ {
+ res.timer_use |= wd_running;
+ }
+ // TODO: Do something about having pretimeout support
+ res.pretimeout = 0;
+ res.expire_flags = 0;
+ // Interval and timeRemaining need converted from milli -> deci seconds
+ res.initial_countdown = htole16(wd_prop.interval / 100);
+ res.present_countdown = htole16(wd_prop.timeRemaining / 100);
+
+ memcpy(response, &res, sizeof(res));
+ *data_len = sizeof(res);
+ return IPMI_CC_OK;
+ }
+ catch (const std::exception& e)
+ {
+ const std::string e_str = std::string("wd_get: ") + e.what();
+ log<level::ERR>(e_str.c_str());
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ catch (...)
+ {
+ log<level::ERR>("wd_get: Unknown Error");
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+}
diff --git a/app/watchdog.hpp b/app/watchdog.hpp
index c09bd1c..5359a33 100644
--- a/app/watchdog.hpp
+++ b/app/watchdog.hpp
@@ -39,3 +39,21 @@ ipmi_ret_t ipmi_app_watchdog_set(
ipmi_response_t response,
ipmi_data_len_t data_len,
ipmi_context_t context);
+
+/** @brief The GET watchdog IPMI command.
+ * @param[in] netfn
+ * @param[in] cmd
+ * @param[in] request
+ * @param[in,out] response
+ * @param[out] data_len
+ * @param[in] context
+ *
+ * @return IPMI_CC_OK on success, an IPMI error code otherwise.
+ */
+ipmi_ret_t ipmi_app_watchdog_get(
+ ipmi_netfn_t netfn,
+ ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+ ipmi_data_len_t data_len,
+ ipmi_context_t context);
OpenPOWER on IntegriCloud