blob: 2b36445413bf010bb8990753584c1191e446e671 [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/**
Matthew Barth17d1fe22017-05-11 15:00:36 -050030 * @brief Create an action function object
31 *
32 * @param[in] action - The action being created
33 *
34 * @return - The created action function object
35 */
36template <typename T>
37auto make_action(T&& action)
38{
39 return Action(std::forward<T>(action));
40}
41
42/**
Matthew Barth38a93a82017-05-11 14:12:27 -050043 * @struct Property Changed
44 * @brief A match filter functor for Dbus property value changed signals
45 *
46 * @tparam T - The type of the property value
47 * @tparam U - The type of the handler
48 */
49template <typename T, typename U>
50struct PropertyChanged
51{
52 PropertyChanged() = delete;
53 ~PropertyChanged() = default;
54 PropertyChanged(const PropertyChanged&) = default;
55 PropertyChanged& operator=(const PropertyChanged&) = default;
56 PropertyChanged(PropertyChanged&&) = default;
57 PropertyChanged& operator=(PropertyChanged&&) = default;
58 PropertyChanged(const char* iface,
59 const char* property,
60 U&& handler) :
61 _iface(iface),
62 _property(property),
63 _handler(std::forward<U>(handler)) { }
64
65 /** @brief Run signal handler function
66 *
67 * Extract the property from the PropertiesChanged
68 * message and run the handler function.
69 */
70 void operator()(sdbusplus::bus::bus&,
71 sdbusplus::message::message& msg,
72 Zone& zone) const
73 {
74 std::map<std::string, sdbusplus::message::variant<T>> properties;
75 const char* iface = nullptr;
76
77 msg.read(iface);
78 if (!iface || strcmp(iface, _iface))
79 {
80 return;
81 }
82
83 msg.read(properties);
84 auto it = properties.find(_property);
85 if (it == properties.cend())
86 {
87 log<level::ERR>("Unable to find property on interface",
88 entry("PROPERTY=%s", _property),
89 entry("INTERFACE=%s", _iface));
90 return;
91 }
92
93 _handler(zone, std::forward<T>(it->second.template get<T>()));
94 }
95
96private:
97 const char* _iface;
98 const char* _property;
99 U _handler;
100};
101
102/**
103 * @brief Used to process a Dbus property changed signal event
104 *
105 * @param[in] iface - Sensor value interface
106 * @param[in] property - Sensor value property
107 * @param[in] handler - Handler function to perform
108 *
109 * @tparam T - The type of the property
110 * @tparam U - The type of the handler
111 */
112template <typename T, typename U>
113auto propertySignal(const char* iface,
114 const char* property,
115 U&& handler)
116{
117 return PropertyChanged<T, U>(iface, property, std::forward<U>(handler));
118}
119
120} // namespace control
121} // namespace fan
122} // namespace phosphor