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 "dbus_interfaces_finder.hpp"
19 #include "utility.hpp"
20 
21 #include <sdbusplus/bus.hpp>
22 
23 #include <functional>
24 #include <memory>
25 #include <string>
26 #include <vector>
27 
28 namespace phosphor::power::util
29 {
30 
31 /**
32  * @class CompatibleSystemTypesFinder
33  *
34  * Class that finds the compatible system types for the current system.
35  *
36  * The compatible system types are in a list ordered from most to least
37  * specific.
38  *
39  * Example:
40  *   - com.acme.Hardware.Chassis.Model.MegaServer4CPU
41  *   - com.acme.Hardware.Chassis.Model.MegaServer
42  *   - com.acme.Hardware.Chassis.Model.Server
43  *
44  * When a list of compatible system types is found, the callback function
45  * specified in the constructor is called.  This function will be called
46  * multiple times if multiple lists of compatible system types are found.
47  */
48 class CompatibleSystemTypesFinder
49 {
50   public:
51     // Specify which compiler-generated methods we want
52     CompatibleSystemTypesFinder() = delete;
53     CompatibleSystemTypesFinder(const CompatibleSystemTypesFinder&) = delete;
54     CompatibleSystemTypesFinder(CompatibleSystemTypesFinder&&) = delete;
55     CompatibleSystemTypesFinder&
56         operator=(const CompatibleSystemTypesFinder&) = delete;
57     CompatibleSystemTypesFinder&
58         operator=(CompatibleSystemTypesFinder&&) = delete;
59     ~CompatibleSystemTypesFinder() = default;
60 
61     /**
62      * Callback function that is called when a list of compatible system types
63      * is found.
64      *
65      * @param compatibleSystemTypes Compatible system types for the current
66      *                              system ordered from most to least specific
67      */
68     using Callback = std::function<void(
69         const std::vector<std::string>& compatibleSystemTypes)>;
70 
71     /**
72      * Constructor.
73      *
74      * Note: The callback function may be called immediately by this
75      * constructor.  For this reason, do not use this constructor in the
76      * initialization list of constructors in other classes.  Otherwise the
77      * callback may be called before the other class is fully initialized,
78      * leading to unpredictable behavior.
79      *
80      * @param bus D-Bus bus object
81      * @param callback Callback function that is called each time a list of
82      *                 compatible system types is found
83      */
84     explicit CompatibleSystemTypesFinder(sdbusplus::bus_t& bus,
85                                          Callback callback);
86 
87     /**
88      * Refind all compatible system types for the current system.
89      *
90      * The callback specified in the constructor will be called for each list of
91      * compatible system types found.
92      *
93      * This method normally does not need to be called.  New lists of compatible
94      * system types are automatically detected using an InterfacesAdded
95      * listener.  However, this method may be useful if the caller is not
96      * currently receiving D-Bus signals (such as within a loop).
97      */
refind()98     void refind()
99     {
100         interfaceFinder->refind();
101     }
102 
103     /**
104      * Callback function that is called when a Compatible interface is found.
105      *
106      * @param path D-Bus object path that implements the interface
107      * @param interface D-Bus interface that was found
108      * @param properties Properties of the D-Bus interface
109      */
110     void interfaceFoundCallback(const std::string& path,
111                                 const std::string& interface,
112                                 const DbusPropertyMap& properties);
113 
114   private:
115     /**
116      * Callback function that is called each time a list of compatible system
117      * types is found.
118      */
119     Callback callback;
120 
121     /**
122      * Class used to find instances of the D-Bus Compatible interface.
123      */
124     std::unique_ptr<DBusInterfacesFinder> interfaceFinder;
125 };
126 
127 } // namespace phosphor::power::util
128