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      * @param bus D-Bus bus object
77      * @param service D-Bus service that owns the object paths implementing
78      *                the specified interfaces
79      * @param interfaces D-Bus interfaces to find
80      * @param callback Callback function that is called each time an interface
81      *                 instance is found
82      */
83     explicit DBusInterfacesFinder(sdbusplus::bus_t& bus,
84                                   const std::string& service,
85                                   const std::vector<std::string>& interfaces,
86                                   Callback callback);
87 
88     /**
89      * Callback function to handle InterfacesAdded D-Bus signals
90      *
91      * @param message Expanded sdbusplus message data
92      */
93     void interfacesAddedCallback(sdbusplus::message_t& message);
94 
95   private:
96     /**
97      * Finds any interface instances that already exist on D-Bus.
98      */
99     void findInterfaces();
100 
101     /**
102      * D-Bus bus object.
103      */
104     sdbusplus::bus_t& bus;
105 
106     /**
107      * D-Bus service that owns the object paths implementing the interfaces.
108      */
109     std::string service;
110 
111     /**
112      * D-Bus interfaces to find.
113      */
114     std::vector<std::string> interfaces;
115 
116     /**
117      * Callback function that is called each time an interface instance is
118      * found.
119      */
120     Callback callback;
121 
122     /**
123      * Match object for InterfacesAdded signals.
124      */
125     sdbusplus::bus::match_t match;
126 };
127 
128 } // namespace phosphor::power::util
129