xref: /openbmc/phosphor-fan-presence/control/functor.hpp (revision 17d1fe23b704cacb1cdd9b58156f354626b36f8c)
138a93a8aSMatthew Barth #pragma once
238a93a8aSMatthew Barth 
338a93a8aSMatthew Barth #include "types.hpp"
438a93a8aSMatthew Barth #include <phosphor-logging/log.hpp>
538a93a8aSMatthew Barth 
638a93a8aSMatthew Barth namespace phosphor
738a93a8aSMatthew Barth {
838a93a8aSMatthew Barth namespace fan
938a93a8aSMatthew Barth {
1038a93a8aSMatthew Barth namespace control
1138a93a8aSMatthew Barth {
1238a93a8aSMatthew Barth class Zone;
1338a93a8aSMatthew Barth 
1438a93a8aSMatthew Barth using namespace phosphor::logging;
1538a93a8aSMatthew Barth 
1638a93a8aSMatthew Barth /**
1738a93a8aSMatthew Barth  * @brief Create a handler function object
1838a93a8aSMatthew Barth  *
1938a93a8aSMatthew Barth  * @param[in] handler - The handler being created
2038a93a8aSMatthew Barth  *
2138a93a8aSMatthew Barth  * @return - The created handler function object
2238a93a8aSMatthew Barth  */
2338a93a8aSMatthew Barth template <typename T>
2438a93a8aSMatthew Barth auto make_handler(T&& handler)
2538a93a8aSMatthew Barth {
2638a93a8aSMatthew Barth     return Handler(std::forward<T>(handler));
2738a93a8aSMatthew Barth }
2838a93a8aSMatthew Barth 
2938a93a8aSMatthew Barth /**
30*17d1fe23SMatthew Barth  * @brief Create an action function object
31*17d1fe23SMatthew Barth  *
32*17d1fe23SMatthew Barth  * @param[in] action - The action being created
33*17d1fe23SMatthew Barth  *
34*17d1fe23SMatthew Barth  * @return - The created action function object
35*17d1fe23SMatthew Barth  */
36*17d1fe23SMatthew Barth template <typename T>
37*17d1fe23SMatthew Barth auto make_action(T&& action)
38*17d1fe23SMatthew Barth {
39*17d1fe23SMatthew Barth     return Action(std::forward<T>(action));
40*17d1fe23SMatthew Barth }
41*17d1fe23SMatthew Barth 
42*17d1fe23SMatthew Barth /**
4338a93a8aSMatthew Barth  * @struct Property Changed
4438a93a8aSMatthew Barth  * @brief A match filter functor for Dbus property value changed signals
4538a93a8aSMatthew Barth  *
4638a93a8aSMatthew Barth  * @tparam T - The type of the property value
4738a93a8aSMatthew Barth  * @tparam U - The type of the handler
4838a93a8aSMatthew Barth  */
4938a93a8aSMatthew Barth template <typename T, typename U>
5038a93a8aSMatthew Barth struct PropertyChanged
5138a93a8aSMatthew Barth {
5238a93a8aSMatthew Barth     PropertyChanged() = delete;
5338a93a8aSMatthew Barth     ~PropertyChanged() = default;
5438a93a8aSMatthew Barth     PropertyChanged(const PropertyChanged&) = default;
5538a93a8aSMatthew Barth     PropertyChanged& operator=(const PropertyChanged&) = default;
5638a93a8aSMatthew Barth     PropertyChanged(PropertyChanged&&) = default;
5738a93a8aSMatthew Barth     PropertyChanged& operator=(PropertyChanged&&) = default;
5838a93a8aSMatthew Barth     PropertyChanged(const char* iface,
5938a93a8aSMatthew Barth                     const char* property,
6038a93a8aSMatthew Barth                     U&& handler) :
6138a93a8aSMatthew Barth         _iface(iface),
6238a93a8aSMatthew Barth         _property(property),
6338a93a8aSMatthew Barth         _handler(std::forward<U>(handler)) { }
6438a93a8aSMatthew Barth 
6538a93a8aSMatthew Barth     /** @brief Run signal handler function
6638a93a8aSMatthew Barth      *
6738a93a8aSMatthew Barth      * Extract the property from the PropertiesChanged
6838a93a8aSMatthew Barth      * message and run the handler function.
6938a93a8aSMatthew Barth      */
7038a93a8aSMatthew Barth     void operator()(sdbusplus::bus::bus&,
7138a93a8aSMatthew Barth                     sdbusplus::message::message& msg,
7238a93a8aSMatthew Barth                     Zone& zone) const
7338a93a8aSMatthew Barth     {
7438a93a8aSMatthew Barth         std::map<std::string, sdbusplus::message::variant<T>> properties;
7538a93a8aSMatthew Barth         const char* iface = nullptr;
7638a93a8aSMatthew Barth 
7738a93a8aSMatthew Barth         msg.read(iface);
7838a93a8aSMatthew Barth         if (!iface || strcmp(iface, _iface))
7938a93a8aSMatthew Barth         {
8038a93a8aSMatthew Barth             return;
8138a93a8aSMatthew Barth         }
8238a93a8aSMatthew Barth 
8338a93a8aSMatthew Barth         msg.read(properties);
8438a93a8aSMatthew Barth         auto it = properties.find(_property);
8538a93a8aSMatthew Barth         if (it == properties.cend())
8638a93a8aSMatthew Barth         {
8738a93a8aSMatthew Barth             log<level::ERR>("Unable to find property on interface",
8838a93a8aSMatthew Barth                             entry("PROPERTY=%s", _property),
8938a93a8aSMatthew Barth                             entry("INTERFACE=%s", _iface));
9038a93a8aSMatthew Barth             return;
9138a93a8aSMatthew Barth         }
9238a93a8aSMatthew Barth 
9338a93a8aSMatthew Barth         _handler(zone, std::forward<T>(it->second.template get<T>()));
9438a93a8aSMatthew Barth     }
9538a93a8aSMatthew Barth 
9638a93a8aSMatthew Barth private:
9738a93a8aSMatthew Barth     const char* _iface;
9838a93a8aSMatthew Barth     const char* _property;
9938a93a8aSMatthew Barth     U _handler;
10038a93a8aSMatthew Barth };
10138a93a8aSMatthew Barth 
10238a93a8aSMatthew Barth /**
10338a93a8aSMatthew Barth  * @brief Used to process a Dbus property changed signal event
10438a93a8aSMatthew Barth  *
10538a93a8aSMatthew Barth  * @param[in] iface - Sensor value interface
10638a93a8aSMatthew Barth  * @param[in] property - Sensor value property
10738a93a8aSMatthew Barth  * @param[in] handler - Handler function to perform
10838a93a8aSMatthew Barth  *
10938a93a8aSMatthew Barth  * @tparam T - The type of the property
11038a93a8aSMatthew Barth  * @tparam U - The type of the handler
11138a93a8aSMatthew Barth  */
11238a93a8aSMatthew Barth template <typename T, typename U>
11338a93a8aSMatthew Barth auto propertySignal(const char* iface,
11438a93a8aSMatthew Barth                     const char* property,
11538a93a8aSMatthew Barth                     U&& handler)
11638a93a8aSMatthew Barth {
11738a93a8aSMatthew Barth     return PropertyChanged<T, U>(iface, property, std::forward<U>(handler));
11838a93a8aSMatthew Barth }
11938a93a8aSMatthew Barth 
12038a93a8aSMatthew Barth } // namespace control
12138a93a8aSMatthew Barth } // namespace fan
12238a93a8aSMatthew Barth } // namespace phosphor
123