blob: 2ef99f41203f2b12fae5261b7fbdaee12e536732 [file] [log] [blame]
Matt Spinler711d51d2019-11-06 09:36:51 -06001/**
2 * Copyright © 2019 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 */
Matt Spinlercad9c2b2019-12-02 15:42:01 -060016#include "config.h"
17
Matt Spinlerc8705e22019-09-11 12:36:07 -050018#include "data_interface.hpp"
19
Matt Spinlerf61f2922020-06-23 11:32:49 -050020#include "util.hpp"
21
Vijay Lobo81b4dca2021-04-29 00:04:00 -050022#include <fmt/format.h>
23
Matt Spinlercad9c2b2019-12-02 15:42:01 -060024#include <fstream>
Vijay Lobo81b4dca2021-04-29 00:04:00 -050025#include <phosphor-logging/log.hpp>
Matt Spinlerf10068d2020-12-02 10:44:08 -060026#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
Matt Spinlera7d9d962019-11-06 15:01:25 -060027
Matt Spinlerc8705e22019-09-11 12:36:07 -050028namespace openpower
29{
30namespace pels
31{
32
33namespace service_name
34{
35constexpr auto objectMapper = "xyz.openbmc_project.ObjectMapper";
Matt Spinlerfcf9a3f2020-07-28 13:21:07 -050036constexpr auto vpdManager = "com.ibm.VPD.Manager";
Matt Spinler34a904c2020-08-05 14:53:28 -050037constexpr auto ledGroupManager = "xyz.openbmc_project.LED.GroupManager";
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -050038constexpr auto logSetting = "xyz.openbmc_project.Settings";
Matt Spinlerc8705e22019-09-11 12:36:07 -050039} // namespace service_name
40
41namespace object_path
42{
43constexpr auto objectMapper = "/xyz/openbmc_project/object_mapper";
44constexpr auto systemInv = "/xyz/openbmc_project/inventory/system";
Matt Spinler6ea4d5f2020-05-20 13:31:07 -050045constexpr auto chassisInv = "/xyz/openbmc_project/inventory/system/chassis";
Vijay Lobo81b4dca2021-04-29 00:04:00 -050046constexpr auto motherBoardInv =
47 "/xyz/openbmc_project/inventory/system/chassis/motherboard";
Matt Spinlerb3d488f2020-02-21 15:30:46 -060048constexpr auto baseInv = "/xyz/openbmc_project/inventory";
Matt Spinler4aa23a12020-02-03 15:05:09 -060049constexpr auto bmcState = "/xyz/openbmc_project/state/bmc0";
50constexpr auto chassisState = "/xyz/openbmc_project/state/chassis0";
Matt Spinlera7d9d962019-11-06 15:01:25 -060051constexpr auto hostState = "/xyz/openbmc_project/state/host0";
Matt Spinlerb3f51862019-12-09 13:55:10 -060052constexpr auto pldm = "/xyz/openbmc_project/pldm";
Matt Spinler9cf3cfd2020-02-03 14:41:55 -060053constexpr auto enableHostPELs =
54 "/xyz/openbmc_project/logging/send_event_logs_to_host";
Matt Spinlerfcf9a3f2020-07-28 13:21:07 -050055constexpr auto vpdManager = "/com/ibm/VPD/Manager";
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -050056constexpr auto logSetting = "/xyz/openbmc_project/logging/settings";
Matt Spinlerc8705e22019-09-11 12:36:07 -050057} // namespace object_path
58
59namespace interface
60{
61constexpr auto dbusProperty = "org.freedesktop.DBus.Properties";
62constexpr auto objectMapper = "xyz.openbmc_project.ObjectMapper";
63constexpr auto invAsset = "xyz.openbmc_project.Inventory.Decorator.Asset";
Matt Spinlerf10068d2020-12-02 10:44:08 -060064constexpr auto bootProgress = "xyz.openbmc_project.State.Boot.Progress";
Matt Spinlerb3f51862019-12-09 13:55:10 -060065constexpr auto pldmRequester = "xyz.openbmc_project.PLDM.Requester";
Matt Spinler9cf3cfd2020-02-03 14:41:55 -060066constexpr auto enable = "xyz.openbmc_project.Object.Enable";
Matt Spinler4aa23a12020-02-03 15:05:09 -060067constexpr auto bmcState = "xyz.openbmc_project.State.BMC";
68constexpr auto chassisState = "xyz.openbmc_project.State.Chassis";
69constexpr auto hostState = "xyz.openbmc_project.State.Host";
Matt Spinlerb3d488f2020-02-21 15:30:46 -060070constexpr auto invMotherboard =
71 "xyz.openbmc_project.Inventory.Item.Board.Motherboard";
72constexpr auto viniRecordVPD = "com.ibm.ipzvpd.VINI";
Ben Tynere32b7e72021-05-18 12:38:40 -050073constexpr auto vsbpRecordVPD = "com.ibm.ipzvpd.VSBP";
Matt Spinler60c4e792020-03-13 13:45:36 -050074constexpr auto locCode = "com.ibm.ipzvpd.Location";
Matt Spinler1ab66962020-10-29 13:21:44 -050075constexpr auto compatible =
76 "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
Matt Spinlerfcf9a3f2020-07-28 13:21:07 -050077constexpr auto vpdManager = "com.ibm.VPD.Manager";
Matt Spinler34a904c2020-08-05 14:53:28 -050078constexpr auto ledGroup = "xyz.openbmc_project.Led.Group";
Matt Spinler993168d2021-04-07 16:05:03 -050079constexpr auto operationalStatus =
80 "xyz.openbmc_project.State.Decorator.OperationalStatus";
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -050081constexpr auto logSetting = "xyz.openbmc_project.Logging.Settings";
Matt Spinlerc8705e22019-09-11 12:36:07 -050082} // namespace interface
83
Matt Spinlerf10068d2020-12-02 10:44:08 -060084using namespace sdbusplus::xyz::openbmc_project::State::Boot::server;
Matt Spinlerb3d488f2020-02-21 15:30:46 -060085using sdbusplus::exception::SdBusError;
Vijay Lobo81b4dca2021-04-29 00:04:00 -050086using namespace phosphor::logging;
Matt Spinlera7d9d962019-11-06 15:01:25 -060087
Matt Spinlerc8705e22019-09-11 12:36:07 -050088DataInterface::DataInterface(sdbusplus::bus::bus& bus) : _bus(bus)
89{
Matt Spinlercad9c2b2019-12-02 15:42:01 -060090 readBMCFWVersion();
91 readServerFWVersion();
Matt Spinler677381b2020-01-23 10:04:29 -060092 readBMCFWVersionID();
Matt Spinler2a28c932020-02-03 14:23:40 -060093
Matt Spinlerf10068d2020-12-02 10:44:08 -060094 // Watch the BootProgress property
Matt Spinler2a28c932020-02-03 14:23:40 -060095 _properties.emplace_back(std::make_unique<PropertyWatcher<DataInterface>>(
Matt Spinlerf10068d2020-12-02 10:44:08 -060096 bus, object_path::hostState, interface::bootProgress, "BootProgress",
97 *this, [this](const auto& value) {
98 auto status = Progress::convertProgressStagesFromString(
99 std::get<std::string>(value));
Matt Spinler2a28c932020-02-03 14:23:40 -0600100
Matt Spinlerf10068d2020-12-02 10:44:08 -0600101 if ((status == Progress::ProgressStages::SystemInitComplete) ||
102 (status == Progress::ProgressStages::OSStart) ||
103 (status == Progress::ProgressStages::OSRunning))
Matt Spinler2a28c932020-02-03 14:23:40 -0600104 {
Matt Spinler4aa23a12020-02-03 15:05:09 -0600105 setHostUp(true);
Matt Spinler2a28c932020-02-03 14:23:40 -0600106 }
107 else
108 {
Matt Spinler4aa23a12020-02-03 15:05:09 -0600109 setHostUp(false);
Matt Spinler2a28c932020-02-03 14:23:40 -0600110 }
111 }));
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600112
113 // Watch the host PEL enable property
114 _properties.emplace_back(std::make_unique<PropertyWatcher<DataInterface>>(
115 bus, object_path::enableHostPELs, interface::enable, "Enabled", *this,
116 [this](const auto& value) {
117 this->_sendPELsToHost = std::get<bool>(value);
118 }));
Matt Spinler4aa23a12020-02-03 15:05:09 -0600119
120 // Watch the BMCState property
121 _properties.emplace_back(std::make_unique<PropertyWatcher<DataInterface>>(
122 bus, object_path::bmcState, interface::bmcState, "CurrentBMCState",
123 *this, [this](const auto& value) {
124 this->_bmcState = std::get<std::string>(value);
125 }));
126
127 // Watch the chassis current and requested power state properties
128 _properties.emplace_back(std::make_unique<InterfaceWatcher<DataInterface>>(
129 bus, object_path::chassisState, interface::chassisState, *this,
130 [this](const auto& properties) {
131 auto state = properties.find("CurrentPowerState");
132 if (state != properties.end())
133 {
134 this->_chassisState = std::get<std::string>(state->second);
135 }
136
137 auto trans = properties.find("RequestedPowerTransition");
138 if (trans != properties.end())
139 {
140 this->_chassisTransition = std::get<std::string>(trans->second);
141 }
142 }));
143
144 // Watch the CurrentHostState property
145 _properties.emplace_back(std::make_unique<PropertyWatcher<DataInterface>>(
146 bus, object_path::hostState, interface::hostState, "CurrentHostState",
147 *this, [this](const auto& value) {
148 this->_hostState = std::get<std::string>(value);
149 }));
Matt Spinlerc8705e22019-09-11 12:36:07 -0500150}
151
Matt Spinler2a28c932020-02-03 14:23:40 -0600152DBusPropertyMap
153 DataInterface::getAllProperties(const std::string& service,
154 const std::string& objectPath,
155 const std::string& interface) const
Matt Spinlerc8705e22019-09-11 12:36:07 -0500156{
157 DBusPropertyMap properties;
158
159 auto method = _bus.new_method_call(service.c_str(), objectPath.c_str(),
160 interface::dbusProperty, "GetAll");
161 method.append(interface);
162 auto reply = _bus.call(method);
163
164 reply.read(properties);
165
166 return properties;
167}
168
Matt Spinlera7d9d962019-11-06 15:01:25 -0600169void DataInterface::getProperty(const std::string& service,
170 const std::string& objectPath,
171 const std::string& interface,
Matt Spinler2a28c932020-02-03 14:23:40 -0600172 const std::string& property,
173 DBusValue& value) const
Matt Spinlera7d9d962019-11-06 15:01:25 -0600174{
175
176 auto method = _bus.new_method_call(service.c_str(), objectPath.c_str(),
177 interface::dbusProperty, "Get");
178 method.append(interface, property);
179 auto reply = _bus.call(method);
180
181 reply.read(value);
182}
183
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600184DBusPathList DataInterface::getPaths(const DBusInterfaceList& interfaces) const
185{
186
187 auto method = _bus.new_method_call(
188 service_name::objectMapper, object_path::objectMapper,
189 interface::objectMapper, "GetSubTreePaths");
190
191 method.append(std::string{"/"}, 0, interfaces);
192
193 auto reply = _bus.call(method);
194
195 DBusPathList paths;
196 reply.read(paths);
197
198 return paths;
199}
200
Matt Spinlerc8705e22019-09-11 12:36:07 -0500201DBusService DataInterface::getService(const std::string& objectPath,
Matt Spinlerb3f51862019-12-09 13:55:10 -0600202 const std::string& interface) const
Matt Spinlerc8705e22019-09-11 12:36:07 -0500203{
204 auto method = _bus.new_method_call(service_name::objectMapper,
205 object_path::objectMapper,
206 interface::objectMapper, "GetObject");
207
208 method.append(objectPath, std::vector<std::string>({interface}));
209
210 auto reply = _bus.call(method);
211
212 std::map<DBusService, DBusInterfaceList> response;
213 reply.read(response);
214
215 if (!response.empty())
216 {
217 return response.begin()->first;
218 }
219
220 return std::string{};
221}
Matt Spinlera7d9d962019-11-06 15:01:25 -0600222
Matt Spinler677381b2020-01-23 10:04:29 -0600223void DataInterface::readBMCFWVersion()
224{
Matt Spinlerf61f2922020-06-23 11:32:49 -0500225 _bmcFWVersion =
226 phosphor::logging::util::getOSReleaseValue("VERSION").value_or("");
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600227}
228
229void DataInterface::readServerFWVersion()
230{
Sumit Kumarcad16202021-05-13 04:06:15 -0500231 auto value =
232 phosphor::logging::util::getOSReleaseValue("VERSION_ID").value_or("");
233 if ((value != "") && (value.find_last_of(')') != std::string::npos))
234 {
235 std::size_t pos = value.find_first_of('(') + 1;
236 _serverFWVersion = value.substr(pos, value.find_last_of(')') - pos);
237 }
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600238}
239
Matt Spinler677381b2020-01-23 10:04:29 -0600240void DataInterface::readBMCFWVersionID()
241{
Matt Spinlerf61f2922020-06-23 11:32:49 -0500242 _bmcFWVersionID =
243 phosphor::logging::util::getOSReleaseValue("VERSION_ID").value_or("");
Matt Spinler677381b2020-01-23 10:04:29 -0600244}
245
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500246std::string DataInterface::getMachineTypeModel() const
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600247{
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500248 std::string model;
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600249 try
250 {
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600251
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500252 auto service = getService(object_path::systemInv, interface::invAsset);
253 if (!service.empty())
254 {
255 DBusValue value;
256 getProperty(service, object_path::systemInv, interface::invAsset,
257 "Model", value);
258
259 model = std::get<std::string>(value);
260 }
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600261 }
262 catch (const std::exception& e)
263 {
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500264 log<level::WARNING>(fmt::format("Failed reading Model property from "
265 "Interface: {} exception: {}",
266 interface::invAsset, e.what())
267 .c_str());
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600268 }
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500269
270 return model;
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600271}
272
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500273std::string DataInterface::getMachineSerialNumber() const
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600274{
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500275 std::string sn;
276 try
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600277 {
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500278
279 auto service = getService(object_path::systemInv, interface::invAsset);
280 if (!service.empty())
281 {
282 DBusValue value;
283 getProperty(service, object_path::systemInv, interface::invAsset,
284 "SerialNumber", value);
285
286 sn = std::get<std::string>(value);
287 }
288 }
289 catch (const std::exception& e)
290 {
291 log<level::WARNING>(
292 fmt::format("Failed reading SerialNumber property from "
293 "Interface: {} exception: {}",
294 interface::invAsset, e.what())
295 .c_str());
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600296 }
297
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500298 return sn;
299}
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600300
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500301std::string DataInterface::getMotherboardCCIN() const
302{
303 std::string ccin;
304
305 try
306 {
307 auto service =
308 getService(object_path::motherBoardInv, interface::viniRecordVPD);
309 if (!service.empty())
310 {
311 DBusValue value;
312 getProperty(service, object_path::motherBoardInv,
313 interface::viniRecordVPD, "CC", value);
314
315 auto cc = std::get<std::vector<uint8_t>>(value);
316 ccin = std::string{cc.begin(), cc.end()};
317 }
318 }
319 catch (const std::exception& e)
320 {
321 log<level::WARNING>(
322 fmt::format("Failed reading Motherboard CCIN property from "
323 "Interface: {} exception: {}",
324 interface::viniRecordVPD, e.what())
325 .c_str());
326 }
327
328 return ccin;
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600329}
330
Ben Tynere32b7e72021-05-18 12:38:40 -0500331std::vector<uint8_t> DataInterface::getSystemIMKeyword() const
332{
333 std::vector<uint8_t> systemIM;
334
335 try
336 {
337 auto service =
338 getService(object_path::motherBoardInv, interface::vsbpRecordVPD);
339 if (!service.empty())
340 {
341 DBusValue value;
342 getProperty(service, object_path::motherBoardInv,
343 interface::vsbpRecordVPD, "IM", value);
344
345 systemIM = std::get<std::vector<uint8_t>>(value);
346 }
347 }
348 catch (const std::exception& e)
349 {
350 log<level::WARNING>(
351 fmt::format("Failed reading System IM property from "
352 "Interface: {} exception: {}",
353 interface::vsbpRecordVPD, e.what())
354 .c_str());
355 }
356
357 return systemIM;
358}
359
Matt Spinler60c4e792020-03-13 13:45:36 -0500360void DataInterface::getHWCalloutFields(const std::string& inventoryPath,
Matt Spinler60c4e792020-03-13 13:45:36 -0500361 std::string& fruPartNumber,
362 std::string& ccin,
363 std::string& serialNumber) const
364{
365 // For now, attempt to get all of the properties directly on the path
366 // passed in. In the future, may need to make use of an algorithm
367 // to figure out which inventory objects actually hold these
368 // interfaces in the case of non FRUs, or possibly another service
369 // will provide this info. Any missing interfaces will result
370 // in exceptions being thrown.
371
Matt Spinler9b90e2a2020-04-14 10:59:04 -0500372 auto service = getService(inventoryPath, interface::viniRecordVPD);
Matt Spinler60c4e792020-03-13 13:45:36 -0500373
374 auto properties =
375 getAllProperties(service, inventoryPath, interface::viniRecordVPD);
376
377 auto value = std::get<std::vector<uint8_t>>(properties["FN"]);
378 fruPartNumber = std::string{value.begin(), value.end()};
379
380 value = std::get<std::vector<uint8_t>>(properties["CC"]);
381 ccin = std::string{value.begin(), value.end()};
382
383 value = std::get<std::vector<uint8_t>>(properties["SN"]);
384 serialNumber = std::string{value.begin(), value.end()};
385}
386
Matt Spinler9b90e2a2020-04-14 10:59:04 -0500387std::string
388 DataInterface::getLocationCode(const std::string& inventoryPath) const
389{
390 auto service = getService(inventoryPath, interface::locCode);
391
392 DBusValue locCode;
393 getProperty(service, inventoryPath, interface::locCode, "LocationCode",
394 locCode);
395
396 return std::get<std::string>(locCode);
397}
398
Matt Spinler5fb24c12020-06-04 11:21:33 -0500399std::string
400 DataInterface::addLocationCodePrefix(const std::string& locationCode)
401{
402 static const std::string locationCodePrefix{"Ufcs-"};
403
Matt Spinler0e4d72e2020-08-05 12:36:53 -0500404 // Technically there are 2 location code prefixes, Ufcs and Umts, so
405 // if it already starts with a U then don't need to do anything.
406 if (locationCode.front() != 'U')
Matt Spinler5fb24c12020-06-04 11:21:33 -0500407 {
408 return locationCodePrefix + locationCode;
409 }
410
411 return locationCode;
412}
413
414std::string DataInterface::expandLocationCode(const std::string& locationCode,
Patrick Williamsd26fa3e2021-04-21 15:22:23 -0500415 uint16_t /*node*/) const
Matt Spinler5fb24c12020-06-04 11:21:33 -0500416{
Matt Spinlerfcf9a3f2020-07-28 13:21:07 -0500417 auto method =
418 _bus.new_method_call(service_name::vpdManager, object_path::vpdManager,
419 interface::vpdManager, "GetExpandedLocationCode");
420
421 method.append(addLocationCodePrefix(locationCode),
422 static_cast<uint16_t>(0));
423
424 auto reply = _bus.call(method);
425
426 std::string expandedLocationCode;
427 reply.read(expandedLocationCode);
428
429 return expandedLocationCode;
Matt Spinler5fb24c12020-06-04 11:21:33 -0500430}
431
Matt Spinler2f9225a2020-08-05 12:58:49 -0500432std::string
433 DataInterface::getInventoryFromLocCode(const std::string& locationCode,
434 uint16_t node, bool expanded) const
Matt Spinler5fb24c12020-06-04 11:21:33 -0500435{
Matt Spinler2f9225a2020-08-05 12:58:49 -0500436 std::string methodName = expanded ? "GetFRUsByExpandedLocationCode"
437 : "GetFRUsByUnexpandedLocationCode";
Matt Spinlerfcf9a3f2020-07-28 13:21:07 -0500438
Matt Spinler2f9225a2020-08-05 12:58:49 -0500439 auto method =
440 _bus.new_method_call(service_name::vpdManager, object_path::vpdManager,
441 interface::vpdManager, methodName.c_str());
442
443 if (expanded)
444 {
445 method.append(locationCode);
446 }
447 else
448 {
449 method.append(addLocationCodePrefix(locationCode), node);
450 }
Matt Spinlerfcf9a3f2020-07-28 13:21:07 -0500451
452 auto reply = _bus.call(method);
453
454 std::vector<sdbusplus::message::object_path> entries;
455 reply.read(entries);
456
457 // Get the shortest entry from the paths received, as this
458 // would be the path furthest up the inventory hierarchy so
459 // would be the parent FRU. There is guaranteed to at least
460 // be one entry if the call didn't fail.
461 std::string shortest{entries[0]};
462
463 std::for_each(entries.begin(), entries.end(),
464 [&shortest](const auto& path) {
465 if (path.str.size() < shortest.size())
466 {
467 shortest = path;
468 }
469 });
470
471 return shortest;
Matt Spinler5fb24c12020-06-04 11:21:33 -0500472}
473
Matt Spinler34a904c2020-08-05 14:53:28 -0500474void DataInterface::assertLEDGroup(const std::string& ledGroup,
475 bool value) const
476{
477 DBusValue variant = value;
478 auto method =
479 _bus.new_method_call(service_name::ledGroupManager, ledGroup.c_str(),
480 interface::dbusProperty, "Set");
481 method.append(interface::ledGroup, "Asserted", variant);
482 _bus.call(method);
483}
484
Matt Spinler993168d2021-04-07 16:05:03 -0500485void DataInterface::setFunctional(const std::string& objectPath,
486 bool value) const
487{
488 DBusValue variant = value;
489 auto service = getService(objectPath, interface::operationalStatus);
490
491 auto method = _bus.new_method_call(service.c_str(), objectPath.c_str(),
492 interface::dbusProperty, "Set");
493
494 method.append(interface::operationalStatus, "Functional", variant);
495 _bus.call(method);
496}
497
Matt Spinler1ab66962020-10-29 13:21:44 -0500498std::vector<std::string> DataInterface::getSystemNames() const
499{
500 DBusSubTree subtree;
501 DBusValue names;
502
503 auto method = _bus.new_method_call(service_name::objectMapper,
504 object_path::objectMapper,
505 interface::objectMapper, "GetSubTree");
506 method.append(std::string{"/"}, 0,
507 std::vector<std::string>{interface::compatible});
508 auto reply = _bus.call(method);
509
510 reply.read(subtree);
511 if (subtree.empty())
512 {
513 throw std::runtime_error("Compatible interface not on D-Bus");
514 }
515
516 const auto& object = *(subtree.begin());
517 const auto& path = object.first;
518 const auto& service = object.second.begin()->first;
519
520 getProperty(service, path, interface::compatible, "Names", names);
521
522 return std::get<std::vector<std::string>>(names);
523}
524
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500525bool DataInterface::getQuiesceOnError() const
526{
527 bool ret = false;
528
529 try
530 {
531 auto service =
532 getService(object_path::logSetting, interface::logSetting);
533 if (!service.empty())
534 {
535 DBusValue value;
536 getProperty(service, object_path::logSetting, interface::logSetting,
537 "QuiesceOnHwError", value);
538
539 ret = std::get<bool>(value);
540 }
541 }
542 catch (const std::exception& e)
543 {
544 log<level::WARNING>(
545 fmt::format("Failed reading QuiesceOnHwError property from "
546 "Interface: {} exception: {}",
547 interface::logSetting, e.what())
548 .c_str());
549 }
550
551 return ret;
552}
553
Matt Spinlerc8705e22019-09-11 12:36:07 -0500554} // namespace pels
555} // namespace openpower