summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--presence/Makefile.am1
-rw-r--r--presence/tach.cpp148
-rw-r--r--presence/tach.hpp110
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
OpenPOWER on IntegriCloud