blob: 88c590a302c7b0fb8f5c00a9b1d48f50efaaf953 [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 /**
Matt Spinlercce14112019-12-11 14:20:36 -060057 * @brief Says if the system is managed by a hardware
58 * management console.
59 * @return bool - If the system is HMC managed
60 */
61 virtual bool isHMCManaged() const
62 {
63 return _hmcManaged;
64 }
65
66 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -060067 * @brief Says if the host is up and running
68 *
69 * @return bool - If the host is running
70 */
71 virtual bool isHostUp() const
72 {
73 return _hostUp;
74 }
75
Matt Spinlerb3f51862019-12-09 13:55:10 -060076 /**
77 * @brief Returns the PLDM instance ID to use for PLDM commands
78 *
79 * The base class implementation just returns zero.
80 *
81 * @param[in] eid - The PLDM EID
82 *
83 * @return uint8_t - The instance ID
84 */
85 virtual uint8_t getPLDMInstanceID(uint8_t eid) const
86 {
87 return 0;
88 }
89
Matt Spinlera7d9d962019-11-06 15:01:25 -060090 using HostStateChangeFunc = std::function<void(bool)>;
91
92 /**
93 * @brief Register a callback function that will get
94 * called on all host on/off transitions.
95 *
96 * The void(bool) function will get passed the new
97 * value of the host state.
98 *
99 * @param[in] name - The subscription name
100 * @param[in] func - The function to run
101 */
102 void subscribeToHostStateChange(const std::string& name,
103 HostStateChangeFunc func)
104 {
105 _hostChangeCallbacks[name] = func;
106 }
107
108 /**
109 * @brief Unsubscribe from host state changes.
110 *
111 * @param[in] name - The subscription name
112 */
113 void unsubscribeFromHostStateChange(const std::string& name)
114 {
115 _hostChangeCallbacks.erase(name);
116 }
117
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600118 /**
119 * @brief Returns the BMC firmware version
120 *
121 * @return std::string - The BMC version
122 */
123 virtual std::string getBMCFWVersion() const
124 {
125 return _bmcFWVersion;
126 }
127
128 /**
129 * @brief Returns the server firmware version
130 *
131 * @return std::string - The server firmware version
132 */
133 virtual std::string getServerFWVersion() const
134 {
135 return _serverFWVersion;
136 }
137
Matt Spinler19e89ce2019-11-06 13:02:23 -0600138 protected:
139 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600140 * @brief Sets the host on/off state and runs any
141 * callback functions (if there was a change).
142 */
143 void setHostState(bool newState)
144 {
145 if (_hostUp != newState)
146 {
147 _hostUp = newState;
148
149 for (auto& [name, func] : _hostChangeCallbacks)
150 {
151 try
152 {
153 func(_hostUp);
154 }
155 catch (std::exception& e)
156 {
157 using namespace phosphor::logging;
158 log<level::ERR>("A host state change callback threw "
159 "an exception");
160 }
161 }
162 }
163 }
164
165 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -0600166 * @brief The machine type-model. Always kept up to date
167 */
168 std::string _machineTypeModel;
169
170 /**
171 * @brief The machine serial number. Always kept up to date
172 */
173 std::string _machineSerialNumber;
Matt Spinlera7d9d962019-11-06 15:01:25 -0600174
175 /**
Matt Spinlercce14112019-12-11 14:20:36 -0600176 * @brief The hardware management console status. Always kept
177 * up to date.
178 */
179 bool _hmcManaged = false;
180
181 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600182 * @brief The host up status. Always kept up to date.
183 */
184 bool _hostUp = false;
185
186 /**
187 * @brief The map of host state change subscriber
188 * names to callback functions.
189 */
190 std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600191
192 /**
193 * @brief The BMC firmware version string
194 */
195 std::string _bmcFWVersion;
196
197 /**
198 * @brief The server firmware version string
199 */
200 std::string _serverFWVersion;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500201};
202
203/**
204 * @class DataInterface
205 *
206 * Concrete implementation of DataInterfaceBase.
207 */
208class DataInterface : public DataInterfaceBase
209{
210 public:
211 DataInterface() = delete;
212 ~DataInterface() = default;
213 DataInterface(const DataInterface&) = default;
214 DataInterface& operator=(const DataInterface&) = default;
215 DataInterface(DataInterface&&) = default;
216 DataInterface& operator=(DataInterface&&) = default;
217
218 /**
219 * @brief Constructor
220 *
221 * @param[in] bus - The sdbusplus bus object
222 */
223 explicit DataInterface(sdbusplus::bus::bus& bus);
224
Matt Spinlerb3f51862019-12-09 13:55:10 -0600225 /**
226 * @brief Returns the PLDM instance ID to use for PLDM commands
227 *
228 * @param[in] eid - The PLDM EID
229 *
230 * @return uint8_t - The instance ID
231 */
232 uint8_t getPLDMInstanceID(uint8_t eid) const override;
233
Matt Spinlerc8705e22019-09-11 12:36:07 -0500234 private:
235 /**
236 * @brief Reads the machine type/model and SN from D-Bus.
237 *
238 * Looks for them on the 'system' inventory object, and also
239 * places a properties changed watch on them to obtain any changes
240 * (or read them for the first time if the inventory isn't ready
241 * when this function runs.)
242 */
243 void readMTMS();
244
245 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600246 * @brief Reads the host state from D-Bus.
247 *
248 * For host on, looks for the values of 'BootComplete' or 'Standby'
249 * in the OperatingSystemState property on the
250 * 'xyz.openbmc_project.State.OperatingSystem.Status' interface
251 * on the '/xyz/openbmc_project/state/host0' path.
252 *
253 * Also adds a properties changed watch on it so the code can be
254 * kept up to date on changes.
255 */
256 void readHostState();
257
258 /**
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600259 * @brief Reads the BMC firmware version string and puts it into
260 * _bmcFWVersion.
261 */
262 void readBMCFWVersion();
263
264 /**
265 * @brief Reads the server firmware version string and puts it into
266 * _serverFWVersion.
267 */
268 void readServerFWVersion();
269
270 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500271 * @brief Finds the D-Bus service name that hosts the
272 * passed in path and interface.
273 *
274 * @param[in] objectPath - The D-Bus object path
275 * @param[in] interface - The D-Bus interface
276 */
277 DBusService getService(const std::string& objectPath,
Matt Spinlerb3f51862019-12-09 13:55:10 -0600278 const std::string& interface) const;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500279 /**
280 * @brief Wrapper for the 'GetAll' properties method call
281 *
282 * @param[in] service - The D-Bus service to call it on
283 * @param[in] objectPath - The D-Bus object path
284 * @param[in] interface - The interface to get the props on
285 *
286 * @return DBusPropertyMap - The property results
287 */
288 DBusPropertyMap getAllProperties(const std::string& service,
289 const std::string& objectPath,
290 const std::string& interface);
291
292 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600293 * @brief Wrapper for the 'Get' properties method call
294 *
295 * @param[in] service - The D-Bus service to call it on
296 * @param[in] objectPath - The D-Bus object path
297 * @param[in] interface - The interface to get the property on
298 * @param[in] property - The property name
299 * @param[out] value - Filled in with the property value.
300 */
301 void getProperty(const std::string& service, const std::string& objectPath,
302 const std::string& interface, const std::string& property,
303 DBusValue& value);
304
305 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500306 * @brief The properties changed callback for the Asset iface
307 * on the system inventory object.
308 *
309 * @param[in] msg - The sdbusplus message of the signal
310 */
311 void sysAssetPropChanged(sdbusplus::message::message& msg);
312
313 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600314 * @brief The properties changed callback for the OperatingSystemStatus
315 * interface on the host state object.
316 *
317 * @param[in] msg - The sdbusplus message of the signal
318 */
319 void osStatePropChanged(sdbusplus::message::message& msg);
320
321 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500322 * @brief The match object for the system path's properties
323 */
324 std::unique_ptr<sdbusplus::bus::match_t> _sysInventoryPropMatch;
325
326 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600327 * @brief The match object for the operating system status.
328 */
329 std::unique_ptr<sdbusplus::bus::match_t> _osStateMatch;
330
331 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500332 * @brief The sdbusplus bus object for making D-Bus calls.
333 */
334 sdbusplus::bus::bus& _bus;
335};
336
337} // namespace pels
338} // namespace openpower