1 /** 2 * Copyright © 2024 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include "utility.hpp" 19 20 #include <sdbusplus/bus.hpp> 21 #include <sdbusplus/bus/match.hpp> 22 23 #include <functional> 24 #include <string> 25 #include <vector> 26 27 namespace phosphor::power::util 28 { 29 30 /** 31 * @class DBusInterfacesFinder 32 * 33 * Class that finds instances of one or more D-Bus interfaces. 34 * 35 * A D-Bus service name and one or more D-Bus interfaces are specified in the 36 * constructor. The class finds instances of those interfaces that are owned by 37 * the service. 38 * 39 * The class finds the instances using two different methods: 40 * - Registers an InterfacesAdded listener for the specified service. Class is 41 * notified when a new interface instance is created on D-Bus. 42 * - Queries the ObjectMapper to find interface instances that already exist. 43 * 44 * Utilizing both methods allows this class to be used before, during, or after 45 * the service has created the interface instances. 46 * 47 * When an interface instance is found, the callback function specified in the 48 * constructor is called. This function will be called multiple times if 49 * multiple instances are found. 50 */ 51 class DBusInterfacesFinder 52 { 53 public: 54 // Specify which compiler-generated methods we want 55 DBusInterfacesFinder() = delete; 56 DBusInterfacesFinder(const DBusInterfacesFinder&) = delete; 57 DBusInterfacesFinder(DBusInterfacesFinder&&) = delete; 58 DBusInterfacesFinder& operator=(const DBusInterfacesFinder&) = delete; 59 DBusInterfacesFinder& operator=(DBusInterfacesFinder&&) = delete; 60 ~DBusInterfacesFinder() = default; 61 62 /** 63 * Callback function that is called when an interface instance is found. 64 * 65 * @param path D-Bus object path that implements the interface 66 * @param interface D-Bus interface that was found 67 * @param properties Properties of the D-Bus interface 68 */ 69 using Callback = std::function<void(const std::string& path, 70 const std::string& interface, 71 const DbusPropertyMap& properties)>; 72 73 /** 74 * Constructor. 75 * 76 * Note: The callback function may be called immediately by this 77 * constructor. For this reason, do not use this constructor in the 78 * initialization list of constructors in other classes. Otherwise the 79 * callback may be called before the other class is fully initialized, 80 * leading to unpredictable behavior. 81 * 82 * @param bus D-Bus bus object 83 * @param service D-Bus service that owns the object paths implementing 84 * the specified interfaces 85 * @param interfaces D-Bus interfaces to find 86 * @param callback Callback function that is called each time an interface 87 * instance is found 88 */ 89 explicit DBusInterfacesFinder(sdbusplus::bus_t& bus, 90 const std::string& service, 91 const std::vector<std::string>& interfaces, 92 Callback callback); 93 94 /** 95 * Refind all instances of the interfaces specified in the constructor. 96 * 97 * The callback specified in the constructor will be called for each 98 * instance found. 99 * 100 * This method normally does not need to be called. New instances are 101 * automatically detected using an InterfacesAdded listener. However, this 102 * method may be useful if the caller is not currently receiving D-Bus 103 * signals (such as within a loop). 104 */ 105 void refind() 106 { 107 findInterfaces(); 108 } 109 110 /** 111 * Callback function to handle InterfacesAdded D-Bus signals 112 * 113 * @param message Expanded sdbusplus message data 114 */ 115 void interfacesAddedCallback(sdbusplus::message_t& message); 116 117 private: 118 /** 119 * Finds any interface instances that already exist on D-Bus. 120 */ 121 void findInterfaces(); 122 123 /** 124 * D-Bus bus object. 125 */ 126 sdbusplus::bus_t& bus; 127 128 /** 129 * D-Bus service that owns the object paths implementing the interfaces. 130 */ 131 std::string service; 132 133 /** 134 * D-Bus interfaces to find. 135 */ 136 std::vector<std::string> interfaces; 137 138 /** 139 * Callback function that is called each time an interface instance is 140 * found. 141 */ 142 Callback callback; 143 144 /** 145 * Match object for InterfacesAdded signals. 146 */ 147 sdbusplus::bus::match_t match; 148 }; 149 150 } // namespace phosphor::power::util 151