summaryrefslogtreecommitdiffstats
path: root/monitor
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2017-04-27 14:21:48 -0500
committerMatt Spinler <spinler@us.ibm.com>2017-05-11 13:52:50 -0500
commitebaae6115ff5248d7f46d065ca96229c1f4e583d (patch)
tree2c8771ab9f47db9c3a07aceb5cb2bba533346ba8 /monitor
parentabf8da369cb1e7094cc00295131502c73ed5cbc1 (diff)
downloadphosphor-fan-presence-ebaae6115ff5248d7f46d065ca96229c1f4e583d.tar.gz
phosphor-fan-presence-ebaae6115ff5248d7f46d065ca96229c1f4e583d.zip
Add dbus support to TachSensor
TachSensor will match on properties changed signals for the Value and Target properties. When these occur, it will load in those properties and then tell the Fan class there was a change. Also, TachSensor will read in the Target property during construction so it will have a valid value to check against right away. Change-Id: I2dc2cacf5804826c6b0e0ea91196cbdaa4d5b893 Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Diffstat (limited to 'monitor')
-rw-r--r--monitor/Makefile.am1
-rw-r--r--monitor/fan.cpp15
-rw-r--r--monitor/fan.hpp12
-rw-r--r--monitor/tach_sensor.cpp190
-rw-r--r--monitor/tach_sensor.hpp66
5 files changed, 283 insertions, 1 deletions
diff --git a/monitor/Makefile.am b/monitor/Makefile.am
index 26b66b5..6c6f4b3 100644
--- a/monitor/Makefile.am
+++ b/monitor/Makefile.am
@@ -11,6 +11,7 @@ phosphor_fan_monitor_SOURCES = \
tach_sensor.cpp
phosphor_fan_monitor_LDADD = \
+ $(top_builddir)/libfan.la \
$(SDBUSPLUS_LIBS) \
$(PHOSPHOR_LOGGING_LIBS)
diff --git a/monitor/fan.cpp b/monitor/fan.cpp
index b29eaab..852d2ba 100644
--- a/monitor/fan.cpp
+++ b/monitor/fan.cpp
@@ -51,6 +51,21 @@ Fan::Fan(sdbusplus::bus::bus& bus,
}
+void Fan::tachChanged()
+{
+ for (auto& s : _sensors)
+ {
+ tachChanged(*s);
+ }
+}
+
+
+void Fan::tachChanged(TachSensor& sensor)
+{
+ //TODO
+}
+
+
uint64_t Fan::getTargetSpeed(const TachSensor& sensor)
{
uint64_t target = 0;
diff --git a/monitor/fan.hpp b/monitor/fan.hpp
index 6cbd370..d79ae31 100644
--- a/monitor/fan.hpp
+++ b/monitor/fan.hpp
@@ -66,6 +66,18 @@ class Fan
std::shared_ptr<sd_event>& events,
const FanDefinition& def);
+ /**
+ * @brief Callback function for when an input sensor changes
+ *
+ * Starts a timer, where if it expires then the sensor
+ * was slow for too long and can be considered not functional.
+ */
+ void tachChanged(TachSensor& sensor);
+
+ /**
+ * @brief Calls tachChanged(sensor) on each sensor
+ */
+ void tachChanged();
private:
diff --git a/monitor/tach_sensor.cpp b/monitor/tach_sensor.cpp
index 3264ddf..c991bb6 100644
--- a/monitor/tach_sensor.cpp
+++ b/monitor/tach_sensor.cpp
@@ -25,7 +25,59 @@ namespace fan
namespace monitor
{
+constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
+constexpr auto FAN_SENSOR_CONTROL_INTF = "xyz.openbmc_project.Control.FanSpeed";
+constexpr auto FAN_SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value";
+constexpr auto FAN_TARGET_PROPERTY = "Target";
+constexpr auto FAN_VALUE_PROPERTY = "Value";
+
+
+/**
+ * @brief Helper function to read a property
+ *
+ * @param[in] interface - the interface the property is on
+ * @param[in] propertName - the name of the property
+ * @param[in] path - the dbus path
+ * @param[in] service - the dbus service
+ * @param[in] bus - the dbus object
+ * @param[out] value - filled in with the property value
+ */
+template<typename T>
+static void readProperty(const std::string& interface,
+ const std::string& propertyName,
+ const std::string& path,
+ const std::string& service,
+ sdbusplus::bus::bus& bus,
+ T& value)
+{
+ sdbusplus::message::variant<T> property;
+
+ try
+ {
+ auto method = bus.new_method_call(service.c_str(),
+ path.c_str(),
+ PROPERTY_INTF,
+ "Get");
+
+ method.append(interface, propertyName);
+
+ auto reply = bus.call(method);
+ if (reply.is_method_error())
+ {
+ throw std::runtime_error(
+ "Error in property get call for path " +
+ path);
+ }
+
+ reply.read(property);
+ value = sdbusplus::message::variant_ns::get<T>(property);
+ }
+ catch (std::exception& e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
+ }
+}
TachSensor::TachSensor(sdbusplus::bus::bus& bus,
@@ -40,7 +92,143 @@ TachSensor::TachSensor(sdbusplus::bus::bus& bus,
_hasTarget(hasTarget),
_timeout(timeout)
{
- //TODO
+ auto service = getService();
+
+ //Load in starting Target and Input values
+ readProperty(FAN_SENSOR_VALUE_INTF,
+ FAN_VALUE_PROPERTY,
+ _name,
+ service,
+ _bus,
+ _tachInput);
+
+ if (_hasTarget)
+ {
+ readProperty(FAN_SENSOR_CONTROL_INTF,
+ FAN_TARGET_PROPERTY,
+ _name,
+ service,
+ _bus,
+ _tachTarget);
+ }
+
+ auto match = getMatchString(FAN_SENSOR_VALUE_INTF);
+
+ tachSignal = std::make_unique<sdbusplus::server::match::match>(
+ _bus,
+ match.c_str(),
+ handleTachChangeSignal,
+ this);
+
+ if (_hasTarget)
+ {
+ match = getMatchString(FAN_SENSOR_CONTROL_INTF);
+
+ targetSignal = std::make_unique<sdbusplus::server::match::match>(
+ _bus,
+ match.c_str(),
+ handleTargetChangeSignal,
+ this);
+ }
+
+}
+
+
+//Can cache this value after openbmc/openbmc#1496 is resolved
+std::string TachSensor::getService()
+{
+ return phosphor::fan::util::getService(_name,
+ FAN_SENSOR_CONTROL_INTF,
+ _bus);
+}
+
+
+std::string TachSensor::getMatchString(const std::string& interface)
+{
+ return std::string("type='signal',"
+ "interface='org.freedesktop.DBus.Properties',"
+ "member='PropertiesChanged',"
+ "arg0namespace='" + interface + "',"
+ "path='" + _name + "'");
+}
+
+
+int TachSensor::handleTachChangeSignal(sd_bus_message* msg,
+ void* usrData,
+ sd_bus_error* err)
+{
+ auto m = sdbusplus::message::message(msg);
+ static_cast<TachSensor*>(usrData)->handleTachChange(m, err);
+ return 0;
+}
+
+
+int TachSensor::handleTargetChangeSignal(sd_bus_message* msg,
+ void* usrData,
+ sd_bus_error* err)
+{
+ auto m = sdbusplus::message::message(msg);
+ static_cast<TachSensor*>(usrData)->handleTargetChange(m, err);
+ return 0;
+}
+
+
+/**
+ * @brief Reads a property from the input message and stores it in value.
+ * T is the value type.
+ *
+ * Note: This can only be called once per message.
+ *
+ * @param[in] msg - the dbus message that contains the data
+ * @param[in] interface - the interface the property is on
+ * @param[in] propertName - the name of the property
+ * @param[out] value - the value to store the property value in
+ */
+template<typename T>
+static void readPropertyFromMessage(sdbusplus::message::message& msg,
+ const std::string& interface,
+ const std::string& propertyName,
+ T& value)
+{
+ std::string sensor;
+ std::map<std::string, sdbusplus::message::variant<T>> data;
+ msg.read(sensor, data);
+
+ if (sensor.compare(interface) == 0)
+ {
+ auto propertyMap = data.find(propertyName);
+ if (propertyMap != data.end())
+ {
+ value = sdbusplus::message::variant_ns::get<T>(
+ propertyMap->second);
+ }
+ }
+}
+
+
+void TachSensor::handleTargetChange(sdbusplus::message::message& msg,
+ sd_bus_error* err)
+{
+ readPropertyFromMessage(msg,
+ FAN_SENSOR_CONTROL_INTF,
+ FAN_TARGET_PROPERTY,
+ _tachTarget);
+
+ //Check all tach sensors on the fan against the target
+ _fan.tachChanged();
+}
+
+
+void TachSensor::handleTachChange(sdbusplus::message::message& msg,
+ sd_bus_error* err)
+{
+ readPropertyFromMessage(msg,
+ FAN_SENSOR_VALUE_INTF,
+ FAN_VALUE_PROPERTY,
+ _tachInput);
+
+ //Check just this sensor against the target
+ _fan.tachChanged(*this);
}
diff --git a/monitor/tach_sensor.hpp b/monitor/tach_sensor.hpp
index df340f5..003763c 100644
--- a/monitor/tach_sensor.hpp
+++ b/monitor/tach_sensor.hpp
@@ -97,6 +97,62 @@ class TachSensor
private:
/**
+ * @brief Returns the service name for reading the sensor
+ */
+ std::string getService();
+
+ /**
+ * @brief Returns the match string to use for matching
+ * on a properties changed signal.
+ */
+ std::string getMatchString(const std::string& interface);
+
+ /**
+ * @brief Callback function for a tach input properties
+ * changed signal
+ *
+ * @param[in] msg - the dbus message
+ * @param[in] data - user data
+ * @param[in] err - dbus error
+ */
+ static int handleTachChangeSignal(sd_bus_message* msg,
+ void* data,
+ sd_bus_error* err);
+
+ /**
+ * @brief Callback function for a Target properties
+ * changed signal
+ *
+ * @param[in] msg - the dbus message
+ * @param[in] data - user data
+ * @param[in] err - dbus error
+ */
+ static int handleTargetChangeSignal(sd_bus_message* msg,
+ void* data,
+ sd_bus_error* err);
+
+ /**
+ * @brief Reads the Target property and stores in _tachTarget.
+ * Also calls Fan::tachChanged().
+ *
+ * @param[in] msg - the dbus message
+ * @param[in] err - dbus error
+ */
+ void handleTargetChange(sdbusplus::message::message& msg,
+ sd_bus_error* err);
+
+ /**
+ * @brief Reads the Value property and stores in _tachInput.
+ * Also calls Fan::tachChanged().
+ *
+ * @param[in] msg - the dbus message
+ * @param[in] err - dbus error
+ */
+ void handleTachChange(sdbusplus::message::message& msg,
+ sd_bus_error* err);
+
+
+ /**
* @brief the dbus object
*/
sdbusplus::bus::bus& _bus;
@@ -139,6 +195,16 @@ class TachSensor
* @brief The timeout value to use
*/
const size_t _timeout;
+
+ /**
+ * @brief The match object for the Value properties changed signal
+ */
+ std::unique_ptr<sdbusplus::server::match::match> tachSignal;
+
+ /**
+ * @brief The match object for the Target properties changed signal
+ */
+ std::unique_ptr<sdbusplus::server::match::match> targetSignal;
};
}
OpenPOWER on IntegriCloud