diff options
author | James Feist <james.feist@linux.intel.com> | 2019-10-09 23:15:13 +0300 |
---|---|---|
committer | Feist, James <james.feist@intel.com> | 2019-10-15 20:14:03 +0300 |
commit | 9fecb52a7a5cd0afebb98efcffac1359289914fd (patch) | |
tree | 81e6758b0cae083958d3978f8f5027fe74a5e7cf | |
parent | 342bc446a047313000529538a8250ab2955c5ddf (diff) | |
download | provingground-9fecb52a7a5cd0afebb98efcffac1359289914fd.tar.xz |
Handle power state changes
We need to check if power is on as the hsbp goes away
during power off. This copies the power logic from
dbus-sensors and uses it to avoid scanning when power
is off.
Tested: Warnings go away
Change-Id: Ie949e7a98eb70592318710f3eecdfe766f71f110
Signed-off-by: James Feist <james.feist@linux.intel.com>
-rw-r--r-- | hsbp-manager/include/utils.hpp | 96 | ||||
-rw-r--r-- | hsbp-manager/src/hsbp_manager.cpp | 16 |
2 files changed, 112 insertions, 0 deletions
diff --git a/hsbp-manager/include/utils.hpp b/hsbp-manager/include/utils.hpp index 986c3b2..0b47a54 100644 --- a/hsbp-manager/include/utils.hpp +++ b/hsbp-manager/include/utils.hpp @@ -14,7 +14,13 @@ // limitations under the License. */ +#include <boost/algorithm/string/predicate.hpp> +#include <boost/asio/io_context.hpp> +#include <boost/asio/steady_timer.hpp> +#include <boost/container/flat_map.hpp> #include <cstdint> +#include <iostream> +#include <sdbusplus/asio/connection.hpp> #include <string> #include <variant> #include <vector> @@ -51,6 +57,20 @@ constexpr const char* interface = "xyz.openbmc_project.Led.Group"; constexpr const char* asserted = "Asserted"; } // namespace ledGroup +namespace properties +{ +constexpr const char* interface = "org.freedesktop.DBus.Properties"; +constexpr const char* get = "Get"; +} // namespace properties + +namespace power +{ +const static constexpr char* busname = "xyz.openbmc_project.State.Host"; +const static constexpr char* interface = "xyz.openbmc_project.State.Host"; +const static constexpr char* path = "/xyz/openbmc_project/state/host0"; +const static constexpr char* property = "CurrentHostState"; +} // namespace power + namespace hsbp { enum class registers : uint8_t @@ -82,3 +102,79 @@ enum class registers : uint8_t }; } // namespace hsbp + +static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr; +static bool powerStatusOn = false; + +bool isPowerOn(void) +{ + if (!powerMatch) + { + throw std::runtime_error("Power Match Not Created"); + } + return powerStatusOn; +} + +void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn) +{ + static boost::asio::steady_timer timer(conn->get_io_context()); + // create a match for powergood changes, first time do a method call to + // cache the correct value + if (powerMatch) + { + return; + } + + powerMatch = std::make_unique<sdbusplus::bus::match::match>( + static_cast<sdbusplus::bus::bus&>(*conn), + "type='signal',interface='" + std::string(properties::interface) + + "',path='" + std::string(power::path) + "',arg0='" + + std::string(power::interface) + "'", + [](sdbusplus::message::message& message) { + std::string objectName; + boost::container::flat_map<std::string, std::variant<std::string>> + values; + message.read(objectName, values); + auto findState = values.find(power::property); + if (findState != values.end()) + { + bool on = boost::ends_with( + std::get<std::string>(findState->second), "Running"); + if (!on) + { + timer.cancel(); + powerStatusOn = false; + return; + } + // on comes too quickly + timer.expires_after(std::chrono::seconds(10)); + timer.async_wait([](boost::system::error_code ec) { + if (ec == boost::asio::error::operation_aborted) + { + return; + } + else if (ec) + { + std::cerr << "Timer error " << ec.message() << "\n"; + return; + } + powerStatusOn = true; + }); + } + }); + + conn->async_method_call( + [](boost::system::error_code ec, + const std::variant<std::string>& state) { + if (ec) + { + // we commonly come up before power control, we'll capture the + // property change later + return; + } + powerStatusOn = + boost::ends_with(std::get<std::string>(state), "Running"); + }, + power::busname, power::path, properties::interface, properties::get, + power::interface, power::property); +} diff --git a/hsbp-manager/src/hsbp_manager.cpp b/hsbp-manager/src/hsbp_manager.cpp index 08874e9..83ebdf3 100644 --- a/hsbp-manager/src/hsbp_manager.cpp +++ b/hsbp-manager/src/hsbp_manager.cpp @@ -95,10 +95,18 @@ struct Led : std::enable_shared_from_this<Led> { return 1; } + + if (!isPowerOn()) + { + std::cerr << "Can't change blink state when power is off\n"; + throw std::runtime_error( + "Can't change blink state when power is off"); + } BlinkPattern pattern = req ? BlinkPattern::error : BlinkPattern::terminate; if (!self->set(pattern)) { + std::cerr << "Can't change blink pattern\n"; throw std::runtime_error("Cannot set blink pattern"); } val = req; @@ -281,6 +289,13 @@ struct Backplane std::cerr << "timer error " << ec.message() << "\n"; return; } + + if (!isPowerOn()) + { + // can't access hsbp when power is off + runTimer(); + return; + } uint8_t curPresence = 0; uint8_t curIFDET = 0; uint8_t curFailed = 0; @@ -857,5 +872,6 @@ int main() }); io.post([]() { populate(); }); + setupPowerMatch(conn); io.run(); } |