blob: ff0aa75cee216017cc61fa9481084a60370ba948 [file] [log] [blame]
Matt Spinlerc8705e22019-09-11 12:36:07 -05001#pragma once
2
Matt Spinlera7d9d962019-11-06 15:01:25 -06003#include <phosphor-logging/log.hpp>
Matt Spinlerc8705e22019-09-11 12:36:07 -05004#include <sdbusplus/bus.hpp>
5#include <sdbusplus/bus/match.hpp>
6
7namespace openpower
8{
9namespace pels
10{
11
12using DBusValue = sdbusplus::message::variant<std::string>;
13using DBusProperty = std::string;
14using DBusInterface = std::string;
15using DBusService = std::string;
16using DBusPath = std::string;
17using DBusInterfaceList = std::vector<DBusInterface>;
18using DBusPropertyMap = std::map<DBusProperty, DBusValue>;
19
20/**
21 * @class DataInterface
22 *
Matt Spinler19e89ce2019-11-06 13:02:23 -060023 * A base class for gathering data about the system for use
24 * in PELs. Implemented this way to facilitate mocking.
Matt Spinlerc8705e22019-09-11 12:36:07 -050025 */
26class DataInterfaceBase
27{
28 public:
29 DataInterfaceBase() = default;
30 virtual ~DataInterfaceBase() = default;
31 DataInterfaceBase(const DataInterfaceBase&) = default;
32 DataInterfaceBase& operator=(const DataInterfaceBase&) = default;
33 DataInterfaceBase(DataInterfaceBase&&) = default;
34 DataInterfaceBase& operator=(DataInterfaceBase&&) = default;
35
36 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -060037 * @brief Returns the machine Type/Model
Matt Spinlerc8705e22019-09-11 12:36:07 -050038 *
39 * @return string - The machine Type/Model string
40 */
Matt Spinler19e89ce2019-11-06 13:02:23 -060041 virtual std::string getMachineTypeModel() const
42 {
43 return _machineTypeModel;
44 }
Matt Spinlerc8705e22019-09-11 12:36:07 -050045
46 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -060047 * @brief Returns the machine serial number
Matt Spinlerc8705e22019-09-11 12:36:07 -050048 *
49 * @return string - The machine serial number
50 */
Matt Spinler19e89ce2019-11-06 13:02:23 -060051 virtual std::string getMachineSerialNumber() const
52 {
53 return _machineSerialNumber;
54 }
55
Matt Spinlera7d9d962019-11-06 15:01:25 -060056 /**
57 * @brief Says if the host is up and running
58 *
59 * @return bool - If the host is running
60 */
61 virtual bool isHostUp() const
62 {
63 return _hostUp;
64 }
65
66 using HostStateChangeFunc = std::function<void(bool)>;
67
68 /**
69 * @brief Register a callback function that will get
70 * called on all host on/off transitions.
71 *
72 * The void(bool) function will get passed the new
73 * value of the host state.
74 *
75 * @param[in] name - The subscription name
76 * @param[in] func - The function to run
77 */
78 void subscribeToHostStateChange(const std::string& name,
79 HostStateChangeFunc func)
80 {
81 _hostChangeCallbacks[name] = func;
82 }
83
84 /**
85 * @brief Unsubscribe from host state changes.
86 *
87 * @param[in] name - The subscription name
88 */
89 void unsubscribeFromHostStateChange(const std::string& name)
90 {
91 _hostChangeCallbacks.erase(name);
92 }
93
Matt Spinlercad9c2b2019-12-02 15:42:01 -060094 /**
95 * @brief Returns the BMC firmware version
96 *
97 * @return std::string - The BMC version
98 */
99 virtual std::string getBMCFWVersion() const
100 {
101 return _bmcFWVersion;
102 }
103
104 /**
105 * @brief Returns the server firmware version
106 *
107 * @return std::string - The server firmware version
108 */
109 virtual std::string getServerFWVersion() const
110 {
111 return _serverFWVersion;
112 }
113
Matt Spinler19e89ce2019-11-06 13:02:23 -0600114 protected:
115 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600116 * @brief Sets the host on/off state and runs any
117 * callback functions (if there was a change).
118 */
119 void setHostState(bool newState)
120 {
121 if (_hostUp != newState)
122 {
123 _hostUp = newState;
124
125 for (auto& [name, func] : _hostChangeCallbacks)
126 {
127 try
128 {
129 func(_hostUp);
130 }
131 catch (std::exception& e)
132 {
133 using namespace phosphor::logging;
134 log<level::ERR>("A host state change callback threw "
135 "an exception");
136 }
137 }
138 }
139 }
140
141 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -0600142 * @brief The machine type-model. Always kept up to date
143 */
144 std::string _machineTypeModel;
145
146 /**
147 * @brief The machine serial number. Always kept up to date
148 */
149 std::string _machineSerialNumber;
Matt Spinlera7d9d962019-11-06 15:01:25 -0600150
151 /**
152 * @brief The host up status. Always kept up to date.
153 */
154 bool _hostUp = false;
155
156 /**
157 * @brief The map of host state change subscriber
158 * names to callback functions.
159 */
160 std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600161
162 /**
163 * @brief The BMC firmware version string
164 */
165 std::string _bmcFWVersion;
166
167 /**
168 * @brief The server firmware version string
169 */
170 std::string _serverFWVersion;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500171};
172
173/**
174 * @class DataInterface
175 *
176 * Concrete implementation of DataInterfaceBase.
177 */
178class DataInterface : public DataInterfaceBase
179{
180 public:
181 DataInterface() = delete;
182 ~DataInterface() = default;
183 DataInterface(const DataInterface&) = default;
184 DataInterface& operator=(const DataInterface&) = default;
185 DataInterface(DataInterface&&) = default;
186 DataInterface& operator=(DataInterface&&) = default;
187
188 /**
189 * @brief Constructor
190 *
191 * @param[in] bus - The sdbusplus bus object
192 */
193 explicit DataInterface(sdbusplus::bus::bus& bus);
194
Matt Spinlerc8705e22019-09-11 12:36:07 -0500195 private:
196 /**
197 * @brief Reads the machine type/model and SN from D-Bus.
198 *
199 * Looks for them on the 'system' inventory object, and also
200 * places a properties changed watch on them to obtain any changes
201 * (or read them for the first time if the inventory isn't ready
202 * when this function runs.)
203 */
204 void readMTMS();
205
206 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600207 * @brief Reads the host state from D-Bus.
208 *
209 * For host on, looks for the values of 'BootComplete' or 'Standby'
210 * in the OperatingSystemState property on the
211 * 'xyz.openbmc_project.State.OperatingSystem.Status' interface
212 * on the '/xyz/openbmc_project/state/host0' path.
213 *
214 * Also adds a properties changed watch on it so the code can be
215 * kept up to date on changes.
216 */
217 void readHostState();
218
219 /**
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600220 * @brief Reads the BMC firmware version string and puts it into
221 * _bmcFWVersion.
222 */
223 void readBMCFWVersion();
224
225 /**
226 * @brief Reads the server firmware version string and puts it into
227 * _serverFWVersion.
228 */
229 void readServerFWVersion();
230
231 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500232 * @brief Finds the D-Bus service name that hosts the
233 * passed in path and interface.
234 *
235 * @param[in] objectPath - The D-Bus object path
236 * @param[in] interface - The D-Bus interface
237 */
238 DBusService getService(const std::string& objectPath,
239 const std::string& interface);
240 /**
241 * @brief Wrapper for the 'GetAll' properties method call
242 *
243 * @param[in] service - The D-Bus service to call it on
244 * @param[in] objectPath - The D-Bus object path
245 * @param[in] interface - The interface to get the props on
246 *
247 * @return DBusPropertyMap - The property results
248 */
249 DBusPropertyMap getAllProperties(const std::string& service,
250 const std::string& objectPath,
251 const std::string& interface);
252
253 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600254 * @brief Wrapper for the 'Get' properties method call
255 *
256 * @param[in] service - The D-Bus service to call it on
257 * @param[in] objectPath - The D-Bus object path
258 * @param[in] interface - The interface to get the property on
259 * @param[in] property - The property name
260 * @param[out] value - Filled in with the property value.
261 */
262 void getProperty(const std::string& service, const std::string& objectPath,
263 const std::string& interface, const std::string& property,
264 DBusValue& value);
265
266 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500267 * @brief The properties changed callback for the Asset iface
268 * on the system inventory object.
269 *
270 * @param[in] msg - The sdbusplus message of the signal
271 */
272 void sysAssetPropChanged(sdbusplus::message::message& msg);
273
274 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600275 * @brief The properties changed callback for the OperatingSystemStatus
276 * interface on the host state object.
277 *
278 * @param[in] msg - The sdbusplus message of the signal
279 */
280 void osStatePropChanged(sdbusplus::message::message& msg);
281
282 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500283 * @brief The match object for the system path's properties
284 */
285 std::unique_ptr<sdbusplus::bus::match_t> _sysInventoryPropMatch;
286
287 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600288 * @brief The match object for the operating system status.
289 */
290 std::unique_ptr<sdbusplus::bus::match_t> _osStateMatch;
291
292 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500293 * @brief The sdbusplus bus object for making D-Bus calls.
294 */
295 sdbusplus::bus::bus& _bus;
296};
297
298} // namespace pels
299} // namespace openpower