138a93a8aSMatthew Barth #pragma once 238a93a8aSMatthew Barth 338a93a8aSMatthew Barth #include "types.hpp" 4336f18a5SMatthew Barth #include "sdbusplus.hpp" 538a93a8aSMatthew Barth #include <phosphor-logging/log.hpp> 638a93a8aSMatthew Barth 738a93a8aSMatthew Barth namespace phosphor 838a93a8aSMatthew Barth { 938a93a8aSMatthew Barth namespace fan 1038a93a8aSMatthew Barth { 1138a93a8aSMatthew Barth namespace control 1238a93a8aSMatthew Barth { 1338a93a8aSMatthew Barth class Zone; 1438a93a8aSMatthew Barth 15336f18a5SMatthew Barth using namespace phosphor::fan; 165a302576SMatthew Barth using namespace sdbusplus::bus::match; 1738a93a8aSMatthew Barth using namespace phosphor::logging; 18336f18a5SMatthew Barth using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: 19336f18a5SMatthew Barth Error::InternalFailure; 2038a93a8aSMatthew Barth 2138a93a8aSMatthew Barth /** 2238a93a8aSMatthew Barth * @brief Create a handler function object 2338a93a8aSMatthew Barth * 2438a93a8aSMatthew Barth * @param[in] handler - The handler being created 2538a93a8aSMatthew Barth * 2638a93a8aSMatthew Barth * @return - The created handler function object 2738a93a8aSMatthew Barth */ 2838a93a8aSMatthew Barth template <typename T> 2938a93a8aSMatthew Barth auto make_handler(T&& handler) 3038a93a8aSMatthew Barth { 3138a93a8aSMatthew Barth return Handler(std::forward<T>(handler)); 3238a93a8aSMatthew Barth } 3338a93a8aSMatthew Barth 3438a93a8aSMatthew Barth /** 3517d1fe23SMatthew Barth * @brief Create an action function object 3617d1fe23SMatthew Barth * 3717d1fe23SMatthew Barth * @param[in] action - The action being created 3817d1fe23SMatthew Barth * 3917d1fe23SMatthew Barth * @return - The created action function object 4017d1fe23SMatthew Barth */ 4117d1fe23SMatthew Barth template <typename T> 4217d1fe23SMatthew Barth auto make_action(T&& action) 4317d1fe23SMatthew Barth { 4417d1fe23SMatthew Barth return Action(std::forward<T>(action)); 4517d1fe23SMatthew Barth } 4617d1fe23SMatthew Barth 4717d1fe23SMatthew Barth /** 4838a93a8aSMatthew Barth * @struct Property Changed 4938a93a8aSMatthew Barth * @brief A match filter functor for Dbus property value changed signals 5038a93a8aSMatthew Barth * 5138a93a8aSMatthew Barth * @tparam T - The type of the property value 5238a93a8aSMatthew Barth * @tparam U - The type of the handler 5338a93a8aSMatthew Barth */ 5438a93a8aSMatthew Barth template <typename T, typename U> 5538a93a8aSMatthew Barth struct PropertyChanged 5638a93a8aSMatthew Barth { 5738a93a8aSMatthew Barth PropertyChanged() = delete; 5838a93a8aSMatthew Barth ~PropertyChanged() = default; 5938a93a8aSMatthew Barth PropertyChanged(const PropertyChanged&) = default; 6038a93a8aSMatthew Barth PropertyChanged& operator=(const PropertyChanged&) = default; 6138a93a8aSMatthew Barth PropertyChanged(PropertyChanged&&) = default; 6238a93a8aSMatthew Barth PropertyChanged& operator=(PropertyChanged&&) = default; 63336f18a5SMatthew Barth PropertyChanged(const char* path, 64336f18a5SMatthew Barth const char* iface, 6538a93a8aSMatthew Barth const char* property, 6638a93a8aSMatthew Barth U&& handler) : 67336f18a5SMatthew Barth _path(path), 6838a93a8aSMatthew Barth _iface(iface), 6938a93a8aSMatthew Barth _property(property), 7038a93a8aSMatthew Barth _handler(std::forward<U>(handler)) { } 7138a93a8aSMatthew Barth 7238a93a8aSMatthew Barth /** @brief Run signal handler function 7338a93a8aSMatthew Barth * 7438a93a8aSMatthew Barth * Extract the property from the PropertiesChanged 75336f18a5SMatthew Barth * message (or read the property when the message is null) 76336f18a5SMatthew Barth * and run the handler function. 7738a93a8aSMatthew Barth */ 78336f18a5SMatthew Barth void operator()(sdbusplus::bus::bus& bus, 7938a93a8aSMatthew Barth sdbusplus::message::message& msg, 8038a93a8aSMatthew Barth Zone& zone) const 8138a93a8aSMatthew Barth { 82336f18a5SMatthew Barth if (msg) 83336f18a5SMatthew Barth { 8438a93a8aSMatthew Barth std::map<std::string, sdbusplus::message::variant<T>> properties; 85*d5cfdbe0SMatthew Barth std::string iface; 8638a93a8aSMatthew Barth 8738a93a8aSMatthew Barth msg.read(iface); 88*d5cfdbe0SMatthew Barth if (iface != _iface) 8938a93a8aSMatthew Barth { 9038a93a8aSMatthew Barth return; 9138a93a8aSMatthew Barth } 9238a93a8aSMatthew Barth 9338a93a8aSMatthew Barth msg.read(properties); 9438a93a8aSMatthew Barth auto it = properties.find(_property); 9538a93a8aSMatthew Barth if (it == properties.cend()) 9638a93a8aSMatthew Barth { 9738a93a8aSMatthew Barth log<level::ERR>("Unable to find property on interface", 9838a93a8aSMatthew Barth entry("PROPERTY=%s", _property), 9938a93a8aSMatthew Barth entry("INTERFACE=%s", _iface)); 10038a93a8aSMatthew Barth return; 10138a93a8aSMatthew Barth } 10238a93a8aSMatthew Barth 10338a93a8aSMatthew Barth _handler(zone, std::forward<T>(it->second.template get<T>())); 10438a93a8aSMatthew Barth } 105336f18a5SMatthew Barth else 106336f18a5SMatthew Barth { 107336f18a5SMatthew Barth try 108336f18a5SMatthew Barth { 109336f18a5SMatthew Barth auto val = util::SDBusPlus::getProperty<T>(bus, 110336f18a5SMatthew Barth _path, 111336f18a5SMatthew Barth _iface, 112336f18a5SMatthew Barth _property); 113336f18a5SMatthew Barth _handler(zone, std::forward<T>(val)); 114336f18a5SMatthew Barth } 115336f18a5SMatthew Barth catch (const InternalFailure& ife) 116336f18a5SMatthew Barth { 117336f18a5SMatthew Barth // Property will not be used unless a property changed 118336f18a5SMatthew Barth // signal message is received for this property. 119336f18a5SMatthew Barth log<level::INFO>( 120336f18a5SMatthew Barth "Property not used, unless PropertyChanged signal received", 121336f18a5SMatthew Barth entry("PATH=%s", _path), 122336f18a5SMatthew Barth entry("INTERFACE=%s", _iface), 123336f18a5SMatthew Barth entry("PROPERTY=%s", _property)); 124336f18a5SMatthew Barth } 125336f18a5SMatthew Barth } 126336f18a5SMatthew Barth } 12738a93a8aSMatthew Barth 12838a93a8aSMatthew Barth private: 129336f18a5SMatthew Barth const char* _path; 13038a93a8aSMatthew Barth const char* _iface; 13138a93a8aSMatthew Barth const char* _property; 13238a93a8aSMatthew Barth U _handler; 13338a93a8aSMatthew Barth }; 13438a93a8aSMatthew Barth 13538a93a8aSMatthew Barth /** 13638a93a8aSMatthew Barth * @brief Used to process a Dbus property changed signal event 13738a93a8aSMatthew Barth * 138336f18a5SMatthew Barth * @param[in] path - Object path 139336f18a5SMatthew Barth * @param[in] iface - Object interface 140336f18a5SMatthew Barth * @param[in] property - Object property 14138a93a8aSMatthew Barth * @param[in] handler - Handler function to perform 14238a93a8aSMatthew Barth * 14338a93a8aSMatthew Barth * @tparam T - The type of the property 14438a93a8aSMatthew Barth * @tparam U - The type of the handler 14538a93a8aSMatthew Barth */ 14638a93a8aSMatthew Barth template <typename T, typename U> 147336f18a5SMatthew Barth auto propertySignal(const char* path, 148336f18a5SMatthew Barth const char* iface, 14938a93a8aSMatthew Barth const char* property, 15038a93a8aSMatthew Barth U&& handler) 15138a93a8aSMatthew Barth { 152336f18a5SMatthew Barth return PropertyChanged<T, U>(path, 153336f18a5SMatthew Barth iface, 154336f18a5SMatthew Barth property, 155336f18a5SMatthew Barth std::forward<U>(handler)); 15638a93a8aSMatthew Barth } 15738a93a8aSMatthew Barth 158eb639c57SMatthew Barth /** 159eb639c57SMatthew Barth * @struct Interface Added 160eb639c57SMatthew Barth * @brief A match filter functor for Dbus interface added signals 161eb639c57SMatthew Barth * 162eb639c57SMatthew Barth * @tparam T - The type of the property value 163eb639c57SMatthew Barth * @tparam U - The type of the handler 164eb639c57SMatthew Barth */ 165eb639c57SMatthew Barth template <typename T, typename U> 166eb639c57SMatthew Barth struct InterfaceAdded 167eb639c57SMatthew Barth { 168eb639c57SMatthew Barth InterfaceAdded() = delete; 169eb639c57SMatthew Barth ~InterfaceAdded() = default; 170eb639c57SMatthew Barth InterfaceAdded(const InterfaceAdded&) = default; 171eb639c57SMatthew Barth InterfaceAdded& operator=(const InterfaceAdded&) = default; 172eb639c57SMatthew Barth InterfaceAdded(InterfaceAdded&&) = default; 173eb639c57SMatthew Barth InterfaceAdded& operator=(InterfaceAdded&&) = default; 174eb639c57SMatthew Barth InterfaceAdded(const char* path, 175eb639c57SMatthew Barth const char* iface, 176eb639c57SMatthew Barth const char* property, 177eb639c57SMatthew Barth U&& handler) : 178eb639c57SMatthew Barth _path(path), 179eb639c57SMatthew Barth _iface(iface), 180eb639c57SMatthew Barth _property(property), 181eb639c57SMatthew Barth _handler(std::forward<U>(handler)) { } 182eb639c57SMatthew Barth 183eb639c57SMatthew Barth /** @brief Run signal handler function 184eb639c57SMatthew Barth * 185eb639c57SMatthew Barth * Extract the property from the InterfacesAdded 186eb639c57SMatthew Barth * message and run the handler function. 187eb639c57SMatthew Barth */ 188eb639c57SMatthew Barth void operator()(sdbusplus::bus::bus&, 189eb639c57SMatthew Barth sdbusplus::message::message& msg, 190eb639c57SMatthew Barth Zone& zone) const 191eb639c57SMatthew Barth { 192336f18a5SMatthew Barth if (msg) 193336f18a5SMatthew Barth { 194eb639c57SMatthew Barth std::map<std::string, 195eb639c57SMatthew Barth std::map<std::string, 196eb639c57SMatthew Barth sdbusplus::message::variant<T>>> intfProp; 197eb639c57SMatthew Barth sdbusplus::message::object_path op; 198eb639c57SMatthew Barth 199eb639c57SMatthew Barth msg.read(op); 200*d5cfdbe0SMatthew Barth if (static_cast<const std::string&>(op) != _path) 201eb639c57SMatthew Barth { 202eb639c57SMatthew Barth // Object path does not match this handler's path 203eb639c57SMatthew Barth return; 204eb639c57SMatthew Barth } 205eb639c57SMatthew Barth 206eb639c57SMatthew Barth msg.read(intfProp); 207eb639c57SMatthew Barth auto itIntf = intfProp.find(_iface); 208eb639c57SMatthew Barth if (itIntf == intfProp.cend()) 209eb639c57SMatthew Barth { 210eb639c57SMatthew Barth // Interface not found on this handler's path 211eb639c57SMatthew Barth return; 212eb639c57SMatthew Barth } 213eb639c57SMatthew Barth auto itProp = itIntf->second.find(_property); 214eb639c57SMatthew Barth if (itProp == itIntf->second.cend()) 215eb639c57SMatthew Barth { 216eb639c57SMatthew Barth // Property not found on this handler's path 217eb639c57SMatthew Barth return; 218eb639c57SMatthew Barth } 219eb639c57SMatthew Barth 220eb639c57SMatthew Barth _handler(zone, std::forward<T>(itProp->second.template get<T>())); 221eb639c57SMatthew Barth } 222336f18a5SMatthew Barth } 223eb639c57SMatthew Barth 224eb639c57SMatthew Barth private: 225eb639c57SMatthew Barth const char* _path; 226eb639c57SMatthew Barth const char* _iface; 227eb639c57SMatthew Barth const char* _property; 228eb639c57SMatthew Barth U _handler; 229eb639c57SMatthew Barth }; 230eb639c57SMatthew Barth 231eb639c57SMatthew Barth /** 232eb639c57SMatthew Barth * @brief Used to process a Dbus interface added signal event 233eb639c57SMatthew Barth * 234eb639c57SMatthew Barth * @param[in] path - Object path 235eb639c57SMatthew Barth * @param[in] iface - Object interface 236eb639c57SMatthew Barth * @param[in] property - Object property 237eb639c57SMatthew Barth * @param[in] handler - Handler function to perform 238eb639c57SMatthew Barth * 239eb639c57SMatthew Barth * @tparam T - The type of the property 240eb639c57SMatthew Barth * @tparam U - The type of the handler 241eb639c57SMatthew Barth */ 242eb639c57SMatthew Barth template <typename T, typename U> 243eb639c57SMatthew Barth auto objectSignal(const char* path, 244eb639c57SMatthew Barth const char* iface, 245eb639c57SMatthew Barth const char* property, 246eb639c57SMatthew Barth U&& handler) 247eb639c57SMatthew Barth { 248eb639c57SMatthew Barth return InterfaceAdded<T, U>(path, 249eb639c57SMatthew Barth iface, 250eb639c57SMatthew Barth property, 251eb639c57SMatthew Barth std::forward<U>(handler)); 252eb639c57SMatthew Barth } 253eb639c57SMatthew Barth 2548fa02dabSMatthew Barth /** 2558fa02dabSMatthew Barth * @struct Name Owner Changed 2568fa02dabSMatthew Barth * @brief A match filter functor for Dbus name owner changed signals 2578fa02dabSMatthew Barth * 2588fa02dabSMatthew Barth * @tparam U - The type of the handler 2598fa02dabSMatthew Barth */ 2608fa02dabSMatthew Barth template <typename U> 2618fa02dabSMatthew Barth struct NameOwnerChanged 2628fa02dabSMatthew Barth { 2638fa02dabSMatthew Barth NameOwnerChanged() = delete; 2648fa02dabSMatthew Barth ~NameOwnerChanged() = default; 2658fa02dabSMatthew Barth NameOwnerChanged(const NameOwnerChanged&) = default; 2668fa02dabSMatthew Barth NameOwnerChanged& operator=(const NameOwnerChanged&) = default; 2678fa02dabSMatthew Barth NameOwnerChanged(NameOwnerChanged&&) = default; 2688fa02dabSMatthew Barth NameOwnerChanged& operator=(NameOwnerChanged&&) = default; 2698fa02dabSMatthew Barth NameOwnerChanged(const char* path, 2708fa02dabSMatthew Barth const char* iface, 2718fa02dabSMatthew Barth U&& handler) : 2728fa02dabSMatthew Barth _path(path), 2738fa02dabSMatthew Barth _iface(iface), 2748fa02dabSMatthew Barth _handler(std::forward<U>(handler)) { } 2758fa02dabSMatthew Barth 2768fa02dabSMatthew Barth /** @brief Run signal handler function 2778fa02dabSMatthew Barth * 2788fa02dabSMatthew Barth * Extract the name owner from the NameOwnerChanged 2798fa02dabSMatthew Barth * message (or read the name owner when the message is null) 2808fa02dabSMatthew Barth * and run the handler function. 2818fa02dabSMatthew Barth */ 2828fa02dabSMatthew Barth void operator()(sdbusplus::bus::bus& bus, 2838fa02dabSMatthew Barth sdbusplus::message::message& msg, 2848fa02dabSMatthew Barth Zone& zone) const 2858fa02dabSMatthew Barth { 2865a302576SMatthew Barth std::string name; 2875a302576SMatthew Barth bool hasOwner = false; 2888fa02dabSMatthew Barth if (msg) 2898fa02dabSMatthew Barth { 2905a302576SMatthew Barth // Handle NameOwnerChanged signals 2915a302576SMatthew Barth msg.read(name); 2925a302576SMatthew Barth 2935a302576SMatthew Barth std::string oldOwn; 2945a302576SMatthew Barth msg.read(oldOwn); 2955a302576SMatthew Barth 2965a302576SMatthew Barth std::string newOwn; 2975a302576SMatthew Barth msg.read(newOwn); 2985a302576SMatthew Barth if (!newOwn.empty()) 2995a302576SMatthew Barth { 3005a302576SMatthew Barth hasOwner = true; 3015a302576SMatthew Barth } 3028fa02dabSMatthew Barth } 3038fa02dabSMatthew Barth else 3048fa02dabSMatthew Barth { 3055a302576SMatthew Barth try 3065a302576SMatthew Barth { 3075a302576SMatthew Barth // Initialize NameOwnerChanged data store with service name 3085a302576SMatthew Barth name = util::SDBusPlus::getService(bus, 3095a302576SMatthew Barth _path, 3105a302576SMatthew Barth _iface); 3115a302576SMatthew Barth hasOwner = util::SDBusPlus::callMethodAndRead<bool>( 3125a302576SMatthew Barth bus, 3135a302576SMatthew Barth "org.freedesktop.DBus", 3145a302576SMatthew Barth "/org/freedesktop/DBus", 3155a302576SMatthew Barth "org.freedesktop.DBus", 3165a302576SMatthew Barth "NameHasOwner", 3175a302576SMatthew Barth name); 3188fa02dabSMatthew Barth } 3195a302576SMatthew Barth catch (const InternalFailure& ife) 3205a302576SMatthew Barth { 3215a302576SMatthew Barth // Failed to get service name owner state 3225a302576SMatthew Barth hasOwner = false; 3235a302576SMatthew Barth } 3245a302576SMatthew Barth } 3255a302576SMatthew Barth 3265a302576SMatthew Barth _handler(zone, name, hasOwner); 3278fa02dabSMatthew Barth } 3288fa02dabSMatthew Barth 3298fa02dabSMatthew Barth private: 3308fa02dabSMatthew Barth const char* _path; 3318fa02dabSMatthew Barth const char* _iface; 3328fa02dabSMatthew Barth U _handler; 3338fa02dabSMatthew Barth }; 3348fa02dabSMatthew Barth 3358fa02dabSMatthew Barth /** 3368fa02dabSMatthew Barth * @brief Used to process a Dbus name owner changed signal event 3378fa02dabSMatthew Barth * 3388fa02dabSMatthew Barth * @param[in] path - Object path 3398fa02dabSMatthew Barth * @param[in] iface - Object interface 3408fa02dabSMatthew Barth * @param[in] handler - Handler function to perform 3418fa02dabSMatthew Barth * 3428fa02dabSMatthew Barth * @tparam U - The type of the handler 3438fa02dabSMatthew Barth * 3448fa02dabSMatthew Barth * @return - The NameOwnerChanged signal struct 3458fa02dabSMatthew Barth */ 3468fa02dabSMatthew Barth template <typename U> 3478fa02dabSMatthew Barth auto ownerSignal(const char* path, 3488fa02dabSMatthew Barth const char* iface, 3498fa02dabSMatthew Barth U&& handler) 3508fa02dabSMatthew Barth { 3518fa02dabSMatthew Barth return NameOwnerChanged<U>(path, 3528fa02dabSMatthew Barth iface, 3538fa02dabSMatthew Barth std::forward<U>(handler)); 3548fa02dabSMatthew Barth } 3558fa02dabSMatthew Barth 35638a93a8aSMatthew Barth } // namespace control 35738a93a8aSMatthew Barth } // namespace fan 35838a93a8aSMatthew Barth } // namespace phosphor 359