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 <cstdint>
24 #include <functional>
25 #include <memory>
26 #include <string>
27 
28 namespace phosphor::power::sequencer
29 {
30 
31 using DbusVariant = phosphor::power::util::DbusVariant;
32 using DbusPropertyMap = phosphor::power::util::DbusPropertyMap;
33 using DBusInterfacesFinder = phosphor::power::util::DBusInterfacesFinder;
34 
35 /**
36  * Power sequencer device properties.
37  */
38 struct DeviceProperties
39 {
40     std::string type;
41     std::string name;
42     uint8_t bus;
43     uint16_t address;
44 };
45 
46 /**
47  * @class DeviceFinder
48  *
49  * Class that finds power sequencer devices in the system.
50  *
51  * When a device is found, the callback function specified in the constructor is
52  * called.  This function will be called multiple times if multiple devices are
53  * found.
54  */
55 class DeviceFinder
56 {
57   public:
58     // Specify which compiler-generated methods we want
59     DeviceFinder() = delete;
60     DeviceFinder(const DeviceFinder&) = delete;
61     DeviceFinder(DeviceFinder&&) = delete;
62     DeviceFinder& operator=(const DeviceFinder&) = delete;
63     DeviceFinder& operator=(DeviceFinder&&) = delete;
64     ~DeviceFinder() = default;
65 
66     /**
67      * Callback function that is called when a power sequencer device is found.
68      *
69      * @param device Device that was found
70      */
71     using Callback = std::function<void(const DeviceProperties& device)>;
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 callback Callback function that is called each time a power
84      *                 sequencer device is found
85      */
86     explicit DeviceFinder(sdbusplus::bus_t& bus, Callback callback);
87 
88     /**
89      * Callback function that is called when a D-Bus interface is found that
90      * contains power sequencer device properties.
91      *
92      * @param path D-Bus object path that implements the interface
93      * @param interface D-Bus interface that was found
94      * @param properties Properties of the D-Bus interface
95      */
96     void interfaceFoundCallback(const std::string& path,
97                                 const std::string& interface,
98                                 const DbusPropertyMap& properties);
99 
100   private:
101     /**
102      * Returns the value of the D-Bus property with the specified name.
103      *
104      * Throws an exception if the property was not found.
105      *
106      * @param properties D-Bus interface properties
107      * @param propertyName D-Bus property name
108      * @return Property value
109      */
110     const DbusVariant& getPropertyValue(const DbusPropertyMap& properties,
111                                         const std::string& propertyName);
112 
113     /**
114      * Callback function that is called each time a power sequencer device is
115      * found.
116      */
117     Callback callback;
118 
119     /**
120      * Class used to find D-Bus interfaces that contain power sequencer device
121      * properties.
122      */
123     std::unique_ptr<DBusInterfacesFinder> interfacesFinder;
124 };
125 
126 } // namespace phosphor::power::sequencer
127