diff options
Diffstat (limited to 'presence')
-rw-r--r-- | presence/Makefile.am | 1 | ||||
-rw-r--r-- | presence/tach.cpp | 148 | ||||
-rw-r--r-- | presence/tach.hpp | 110 |
3 files changed, 259 insertions, 0 deletions
diff --git a/presence/Makefile.am b/presence/Makefile.am index e06a135..2ea4929 100644 --- a/presence/Makefile.am +++ b/presence/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS = \ phosphor_fan_presence_tach_SOURCES = \ fan.cpp \ + tach.cpp \ fan_enclosure.cpp \ tach_sensor.cpp \ tach_detect.cpp diff --git a/presence/tach.cpp b/presence/tach.cpp new file mode 100644 index 0000000..deed040 --- /dev/null +++ b/presence/tach.cpp @@ -0,0 +1,148 @@ +/** + * Copyright © 2017 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string> +#include <tuple> +#include <vector> +#include "tach.hpp" +#include "rpolicy.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +using namespace std::literals::string_literals; + +static const auto tachNamespace = "/xyz/openbmc_project/sensors/fan_tach/"s; +static const auto tachIface = "xyz.openbmc_project.Sensor.Value"s; +static const auto tachProperty = "Value"s; + +Tach::Tach( + const std::vector<std::string>& sensors) : currentState(false) +{ + // Initialize state. + for (const auto& s : sensors) + { + state.emplace_back(s, nullptr, 0); + } +} + +bool Tach::start() +{ + for (size_t i = 0; i < state.size(); ++i) + { + auto& s = state[i]; + auto tachPath = tachNamespace + std::get<std::string>(s); + + // Register for signal callbacks. + std::get<1>(s) = std::make_unique<sdbusplus::bus::match::match>( + util::SDBusPlus::getBus(), + sdbusplus::bus::match::rules::propertiesChanged( + tachPath, tachIface), + [this, i](auto& msg){ this->propertiesChanged(i, msg);}); + + // Get an initial tach speed. + std::get<int64_t>(s) = util::SDBusPlus::getProperty<int64_t>( + tachPath, + tachIface, + tachProperty); + } + + // Set the initial state of the sensor. + currentState = std::any_of( + state.begin(), + state.end(), + [](const auto & s) + { + return std::get<int64_t>(s) != 0; + }); + + return currentState; +} + +void Tach::stop() +{ + for (auto& s : state) + { + // De-register signal callbacks. + std::get<1>(s) = nullptr; + } +} + +bool Tach::present() +{ + // Live query the tach readings. + std::vector<int64_t> values; + for (const auto& s : state) + { + values.push_back( + util::SDBusPlus::getProperty<int64_t>( + tachNamespace + std::get<std::string>(s), + tachIface, + tachProperty)); + } + + return std::any_of( + values.begin(), + values.end(), + [](const auto & v) {return v != 0;}); +} + +void Tach::propertiesChanged( + size_t sensor, + sdbusplus::message::message& msg) +{ + std::string iface; + util::Properties<int64_t> properties; + msg.read(iface, properties); + + propertiesChanged(sensor, properties); +} + +void Tach::propertiesChanged( + size_t sensor, + const util::Properties<int64_t>& props) +{ + auto& s = state[sensor]; + + // Find the Value property containing the speed. + auto it = props.find(tachProperty); + if (it != props.end()) + { + std::get<int64_t>(s) = + sdbusplus::message::variant_ns::get<int64_t>(it->second); + + auto newState = std::any_of( + state.begin(), + state.end(), + [](const auto & s) + { + return std::get<int64_t>(s) != 0; + }); + + if (currentState != newState) + { + getPolicy().stateChanged(newState); + currentState = newState; + } + } +} + +} // namespace presence +} // namespace fan +} // namespace phosphor diff --git a/presence/tach.hpp b/presence/tach.hpp new file mode 100644 index 0000000..4f02521 --- /dev/null +++ b/presence/tach.hpp @@ -0,0 +1,110 @@ +#pragma once + +#include <sdbusplus/message.hpp> +#include <sdbusplus/bus/match.hpp> +#include <string> +#include <vector> +#include "psensor.hpp" +#include "sdbusplus.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ +class RedundancyPolicy; + +/** + * @class Tach + * @brief Fan tach sensor presence implementation. + * + * The Tach class uses one or more tach speed indicators + * to determine presence state. + */ +class Tach : public PresenceSensor +{ + public: + /** + * @brief + * + * Cannot move or copy due to this ptr as context + * for sdbus callbacks. + */ + Tach() = delete; + Tach(const Tach&) = delete; + Tach& operator=(const Tach&) = delete; + Tach(Tach&&) = delete; + Tach& operator=(Tach&&) = delete; + ~Tach() = default; + + /** + * @brief ctor + * + * @param[in] sensors - Fan tach sensors for this psensor. + */ + Tach(const std::vector<std::string>& sensors); + + /** + * @brief start + * + * Register for dbus signal callbacks on fan + * tach sensor change. Query initial tach speeds. + * + * @return The current sensor state. + */ + bool start() override; + + /** + * @brief stop + * + * De-register dbus signal callbacks. + */ + void stop() override; + + /** + * @brief Check the sensor. + * + * Query the tach speeds. + */ + bool present() override; + + private : + /** + * @brief Get the policy associated with this sensor. + */ + virtual RedundancyPolicy& getPolicy() = 0; + + /** + * @brief Properties changed handler for tach sensor updates. + * + * @param[in] sensor - The sensor that changed. + * @param[in] props - The properties that changed. + */ + void propertiesChanged( + size_t sensor, + const phosphor::fan::util::Properties<int64_t>& props); + + /** + * @brief Properties changed handler for tach sensor updates. + * + * @param[in] sensor - The sensor that changed. + * @param[in] msg - The sdbusplus signal message. + */ + void propertiesChanged( + size_t sensor, + sdbusplus::message::message& msg); + + /** @brief array of tach sensors dbus matches, and tach values. */ + std::vector<std::tuple< + std::string, + std::unique_ptr<sdbusplus::bus::match::match>, + int64_t>> state; + + /** The current state of the sensor. */ + bool currentState; +}; + +} // namespace presence +} // namespace fan +} // namespace phosphor |