blob: f2f3a787cbdce5722603d37294ad94a3c8c90b90 [file] [log] [blame]
Matthew Barth38a93a82017-05-11 14:12:27 -05001#pragma once
2
3#include "types.hpp"
4#include <phosphor-logging/log.hpp>
5
6namespace phosphor
7{
8namespace fan
9{
10namespace control
11{
12class Zone;
13
14using namespace phosphor::logging;
15
16/**
17 * @brief Create a handler function object
18 *
19 * @param[in] handler - The handler being created
20 *
21 * @return - The created handler function object
22 */
23template <typename T>
24auto make_handler(T&& handler)
25{
26 return Handler(std::forward<T>(handler));
27}
28
29/**
30 * @struct Property Changed
31 * @brief A match filter functor for Dbus property value changed signals
32 *
33 * @tparam T - The type of the property value
34 * @tparam U - The type of the handler
35 */
36template <typename T, typename U>
37struct PropertyChanged
38{
39 PropertyChanged() = delete;
40 ~PropertyChanged() = default;
41 PropertyChanged(const PropertyChanged&) = default;
42 PropertyChanged& operator=(const PropertyChanged&) = default;
43 PropertyChanged(PropertyChanged&&) = default;
44 PropertyChanged& operator=(PropertyChanged&&) = default;
45 PropertyChanged(const char* iface,
46 const char* property,
47 U&& handler) :
48 _iface(iface),
49 _property(property),
50 _handler(std::forward<U>(handler)) { }
51
52 /** @brief Run signal handler function
53 *
54 * Extract the property from the PropertiesChanged
55 * message and run the handler function.
56 */
57 void operator()(sdbusplus::bus::bus&,
58 sdbusplus::message::message& msg,
59 Zone& zone) const
60 {
61 std::map<std::string, sdbusplus::message::variant<T>> properties;
62 const char* iface = nullptr;
63
64 msg.read(iface);
65 if (!iface || strcmp(iface, _iface))
66 {
67 return;
68 }
69
70 msg.read(properties);
71 auto it = properties.find(_property);
72 if (it == properties.cend())
73 {
74 log<level::ERR>("Unable to find property on interface",
75 entry("PROPERTY=%s", _property),
76 entry("INTERFACE=%s", _iface));
77 return;
78 }
79
80 _handler(zone, std::forward<T>(it->second.template get<T>()));
81 }
82
83private:
84 const char* _iface;
85 const char* _property;
86 U _handler;
87};
88
89/**
90 * @brief Used to process a Dbus property changed signal event
91 *
92 * @param[in] iface - Sensor value interface
93 * @param[in] property - Sensor value property
94 * @param[in] handler - Handler function to perform
95 *
96 * @tparam T - The type of the property
97 * @tparam U - The type of the handler
98 */
99template <typename T, typename U>
100auto propertySignal(const char* iface,
101 const char* property,
102 U&& handler)
103{
104 return PropertyChanged<T, U>(iface, property, std::forward<U>(handler));
105}
106
107} // namespace control
108} // namespace fan
109} // namespace phosphor