blob: 35e220c2dbd05d8466efdcd2c72364d7a3863dc2 [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
Matt Spinlerb3f51862019-12-09 13:55:10 -060066 /**
67 * @brief Returns the PLDM instance ID to use for PLDM commands
68 *
69 * The base class implementation just returns zero.
70 *
71 * @param[in] eid - The PLDM EID
72 *
73 * @return uint8_t - The instance ID
74 */
75 virtual uint8_t getPLDMInstanceID(uint8_t eid) const
76 {
77 return 0;
78 }
79
Matt Spinlera7d9d962019-11-06 15:01:25 -060080 using HostStateChangeFunc = std::function<void(bool)>;
81
82 /**
83 * @brief Register a callback function that will get
84 * called on all host on/off transitions.
85 *
86 * The void(bool) function will get passed the new
87 * value of the host state.
88 *
89 * @param[in] name - The subscription name
90 * @param[in] func - The function to run
91 */
92 void subscribeToHostStateChange(const std::string& name,
93 HostStateChangeFunc func)
94 {
95 _hostChangeCallbacks[name] = func;
96 }
97
98 /**
99 * @brief Unsubscribe from host state changes.
100 *
101 * @param[in] name - The subscription name
102 */
103 void unsubscribeFromHostStateChange(const std::string& name)
104 {
105 _hostChangeCallbacks.erase(name);
106 }
107
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600108 /**
109 * @brief Returns the BMC firmware version
110 *
111 * @return std::string - The BMC version
112 */
113 virtual std::string getBMCFWVersion() const
114 {
115 return _bmcFWVersion;
116 }
117
118 /**
119 * @brief Returns the server firmware version
120 *
121 * @return std::string - The server firmware version
122 */
123 virtual std::string getServerFWVersion() const
124 {
125 return _serverFWVersion;
126 }
127
Matt Spinler19e89ce2019-11-06 13:02:23 -0600128 protected:
129 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600130 * @brief Sets the host on/off state and runs any
131 * callback functions (if there was a change).
132 */
133 void setHostState(bool newState)
134 {
135 if (_hostUp != newState)
136 {
137 _hostUp = newState;
138
139 for (auto& [name, func] : _hostChangeCallbacks)
140 {
141 try
142 {
143 func(_hostUp);
144 }
145 catch (std::exception& e)
146 {
147 using namespace phosphor::logging;
148 log<level::ERR>("A host state change callback threw "
149 "an exception");
150 }
151 }
152 }
153 }
154
155 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -0600156 * @brief The machine type-model. Always kept up to date
157 */
158 std::string _machineTypeModel;
159
160 /**
161 * @brief The machine serial number. Always kept up to date
162 */
163 std::string _machineSerialNumber;
Matt Spinlera7d9d962019-11-06 15:01:25 -0600164
165 /**
166 * @brief The host up status. Always kept up to date.
167 */
168 bool _hostUp = false;
169
170 /**
171 * @brief The map of host state change subscriber
172 * names to callback functions.
173 */
174 std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600175
176 /**
177 * @brief The BMC firmware version string
178 */
179 std::string _bmcFWVersion;
180
181 /**
182 * @brief The server firmware version string
183 */
184 std::string _serverFWVersion;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500185};
186
187/**
188 * @class DataInterface
189 *
190 * Concrete implementation of DataInterfaceBase.
191 */
192class DataInterface : public DataInterfaceBase
193{
194 public:
195 DataInterface() = delete;
196 ~DataInterface() = default;
197 DataInterface(const DataInterface&) = default;
198 DataInterface& operator=(const DataInterface&) = default;
199 DataInterface(DataInterface&&) = default;
200 DataInterface& operator=(DataInterface&&) = default;
201
202 /**
203 * @brief Constructor
204 *
205 * @param[in] bus - The sdbusplus bus object
206 */
207 explicit DataInterface(sdbusplus::bus::bus& bus);
208
Matt Spinlerb3f51862019-12-09 13:55:10 -0600209 /**
210 * @brief Returns the PLDM instance ID to use for PLDM commands
211 *
212 * @param[in] eid - The PLDM EID
213 *
214 * @return uint8_t - The instance ID
215 */
216 uint8_t getPLDMInstanceID(uint8_t eid) const override;
217
Matt Spinlerc8705e22019-09-11 12:36:07 -0500218 private:
219 /**
220 * @brief Reads the machine type/model and SN from D-Bus.
221 *
222 * Looks for them on the 'system' inventory object, and also
223 * places a properties changed watch on them to obtain any changes
224 * (or read them for the first time if the inventory isn't ready
225 * when this function runs.)
226 */
227 void readMTMS();
228
229 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600230 * @brief Reads the host state from D-Bus.
231 *
232 * For host on, looks for the values of 'BootComplete' or 'Standby'
233 * in the OperatingSystemState property on the
234 * 'xyz.openbmc_project.State.OperatingSystem.Status' interface
235 * on the '/xyz/openbmc_project/state/host0' path.
236 *
237 * Also adds a properties changed watch on it so the code can be
238 * kept up to date on changes.
239 */
240 void readHostState();
241
242 /**
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600243 * @brief Reads the BMC firmware version string and puts it into
244 * _bmcFWVersion.
245 */
246 void readBMCFWVersion();
247
248 /**
249 * @brief Reads the server firmware version string and puts it into
250 * _serverFWVersion.
251 */
252 void readServerFWVersion();
253
254 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500255 * @brief Finds the D-Bus service name that hosts the
256 * passed in path and interface.
257 *
258 * @param[in] objectPath - The D-Bus object path
259 * @param[in] interface - The D-Bus interface
260 */
261 DBusService getService(const std::string& objectPath,
Matt Spinlerb3f51862019-12-09 13:55:10 -0600262 const std::string& interface) const;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500263 /**
264 * @brief Wrapper for the 'GetAll' properties method call
265 *
266 * @param[in] service - The D-Bus service to call it on
267 * @param[in] objectPath - The D-Bus object path
268 * @param[in] interface - The interface to get the props on
269 *
270 * @return DBusPropertyMap - The property results
271 */
272 DBusPropertyMap getAllProperties(const std::string& service,
273 const std::string& objectPath,
274 const std::string& interface);
275
276 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600277 * @brief Wrapper for the 'Get' properties method call
278 *
279 * @param[in] service - The D-Bus service to call it on
280 * @param[in] objectPath - The D-Bus object path
281 * @param[in] interface - The interface to get the property on
282 * @param[in] property - The property name
283 * @param[out] value - Filled in with the property value.
284 */
285 void getProperty(const std::string& service, const std::string& objectPath,
286 const std::string& interface, const std::string& property,
287 DBusValue& value);
288
289 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500290 * @brief The properties changed callback for the Asset iface
291 * on the system inventory object.
292 *
293 * @param[in] msg - The sdbusplus message of the signal
294 */
295 void sysAssetPropChanged(sdbusplus::message::message& msg);
296
297 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600298 * @brief The properties changed callback for the OperatingSystemStatus
299 * interface on the host state object.
300 *
301 * @param[in] msg - The sdbusplus message of the signal
302 */
303 void osStatePropChanged(sdbusplus::message::message& msg);
304
305 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500306 * @brief The match object for the system path's properties
307 */
308 std::unique_ptr<sdbusplus::bus::match_t> _sysInventoryPropMatch;
309
310 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600311 * @brief The match object for the operating system status.
312 */
313 std::unique_ptr<sdbusplus::bus::match_t> _osStateMatch;
314
315 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500316 * @brief The sdbusplus bus object for making D-Bus calls.
317 */
318 sdbusplus::bus::bus& _bus;
319};
320
321} // namespace pels
322} // namespace openpower