1 /**
2  * Copyright © 2020 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 "services.hpp"
19 #include "system.hpp"
20 
21 #include <interfaces/manager_interface.hpp>
22 #include <sdbusplus/bus.hpp>
23 #include <sdbusplus/bus/match.hpp>
24 #include <sdbusplus/server/object.hpp>
25 #include <sdeventplus/event.hpp>
26 #include <sdeventplus/source/signal.hpp>
27 #include <sdeventplus/utility/timer.hpp>
28 
29 #include <filesystem>
30 #include <memory>
31 #include <string>
32 #include <vector>
33 
34 namespace phosphor::power::regulators
35 {
36 
37 using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
38 
39 using ManagerObject = sdbusplus::server::object::object<
40     phosphor::power::regulators::interface::ManagerInterface>;
41 
42 class Manager : public ManagerObject
43 {
44   public:
45     Manager() = delete;
46     Manager(const Manager&) = delete;
47     Manager(Manager&&) = delete;
48     Manager& operator=(const Manager&) = delete;
49     Manager& operator=(Manager&&) = delete;
50     ~Manager() = default;
51 
52     /**
53      * Constructor
54      * Creates a manager over the regulators.
55      *
56      * @param bus the D-Bus bus
57      * @param event the sdevent event
58      */
59     Manager(sdbusplus::bus::bus& bus, const sdeventplus::Event& event);
60 
61     /**
62      * Overridden manager object's configure method
63      */
64     void configure() override;
65 
66     /**
67      * Callback function to handle interfacesAdded D-Bus signals
68      *
69      * @param msg Expanded sdbusplus message data
70      */
71     void interfacesAddedHandler(sdbusplus::message::message& msg);
72 
73     /**
74      * Overridden manager object's monitor method
75      *
76      * @param enable Enable or disable regulator monitoring
77      */
78     void monitor(bool enable) override;
79 
80     /**
81      * Callback function to handle receiving a HUP signal
82      * to reload the configuration data.
83      *
84      * @param sigSrc sd_event_source signal wrapper
85      * @param sigInfo signal info on signal fd
86      */
87     void sighupHandler(sdeventplus::source::Signal& sigSrc,
88                        const struct signalfd_siginfo* sigInfo);
89 
90     /**
91      * Timer expired callback function
92      */
93     void timerExpired();
94 
95   private:
96     /**
97      * Clear any cached data or error history related to hardware devices.
98      *
99      * This method should be called when the system is powering on (booting).
100      * While the system was powered off, hardware could have been added,
101      * removed, or replaced.
102      */
103     void clearHardwareData();
104 
105     /**
106      * Finds the list of compatible system types using D-Bus methods.
107      *
108      * This list is used to find the correct JSON configuration file for the
109      * current system.
110      *
111      * Note that some systems do not support the D-Bus compatible interface.
112      *
113      * If a list of compatible system types is found, it is stored in the
114      * compatibleSystemTypes data member.
115      */
116     void findCompatibleSystemTypes();
117 
118     /**
119      * Finds the JSON configuration file.
120      *
121      * Looks for a configuration file based on the list of compatable system
122      * types.  If no file is found, looks for a file with the default name.
123      *
124      * Looks for the file in the test directory and standard directory.
125      *
126      * Throws an exception if an operating system error occurs while checking
127      * for the existance of a file.
128      *
129      * @return absolute path to config file, or an empty path if none found
130      */
131     std::filesystem::path findConfigFile();
132 
133     /**
134      * Loads the JSON configuration file.
135      *
136      * Looks for the config file using findConfigFile().
137      *
138      * If the config file is found, it is parsed and the resulting information
139      * is stored in the system data member.  If parsing fails, an error is
140      * logged.
141      */
142     void loadConfigFile();
143 
144     /**
145      * The D-Bus bus
146      */
147     sdbusplus::bus::bus& bus;
148 
149     /**
150      * Event to loop on
151      */
152     sdeventplus::Event eventLoop;
153 
154     /**
155      * System services like error logging and the journal.
156      */
157     BMCServices services;
158 
159     /**
160      * List of event timers
161      */
162     std::vector<Timer> timers{};
163 
164     /**
165      * List of dbus signal matches
166      */
167     std::vector<std::unique_ptr<sdbusplus::bus::match::match>> signals{};
168 
169     /**
170      * List of compatible system types for the current system.
171      *
172      * Used to find the JSON configuration file.
173      */
174     std::vector<std::string> compatibleSystemTypes{};
175 
176     /**
177      * Computer system being controlled and monitored by the BMC.
178      *
179      * Contains the information loaded from the JSON configuration file.
180      * Contains nullptr if the configuration file has not been loaded.
181      */
182     std::unique_ptr<System> system{};
183 };
184 
185 } // namespace phosphor::power::regulators
186