Support LED control for phosphor-nvme
- Add logic control of the LED
- Set inventory of NVMe drive to D-bus inventory manager
Change-Id: Ie1ef6b1a4523fcc80c3c2e9d274edd6fd02b2990
Signed-off-by: Tony Lee <tony.lee@quantatw.com>
diff --git a/meson.build b/meson.build
index 93a1537..19506df 100644
--- a/meson.build
+++ b/meson.build
@@ -32,6 +32,16 @@
conf_data.set('NVME_OBJ_PATH_ROOT', '"/xyz/openbmc_project/sensors/temperature"')
conf_data.set('NVME_OBJ_PATH', '"/xyz/openbmc_project/sensors/temperature/nvme"')
conf_data.set('DBUS_PROPERTY_IFACE', '"org.freedesktop.DBus.Properties"')
+conf_data.set('LED_GROUP_BUSNAME', '"xyz.openbmc_project.LED.GroupManager"')
+conf_data.set('LED_GROUP_IFACE', '"xyz.openbmc_project.Led.Group"')
+conf_data.set('LED_CONTROLLER_IFACE', '"xyz.openbmc_project.Led.Physical"')
+conf_data.set('ITEM_IFACE', '"xyz.openbmc_project.Inventory.Item"')
+conf_data.set('NVME_STATUS_IFACE', '"xyz.openbmc_project.Nvme.Status"')
+conf_data.set('ASSET_IFACE', '"xyz.openbmc_project.Inventory.Decorator.Asset"')
+conf_data.set('INVENTORY_BUSNAME', '"xyz.openbmc_project.Inventory.Manager"')
+conf_data.set('NVME_INVENTORY_PATH', '"/xyz/openbmc_project/inventory/system/chassis/motherboard/nvme"')
+conf_data.set('INVENTORY_NAMESPACE', '"/xyz/openbmc_project/inventory"')
+conf_data.set('INVENTORY_MANAGER_IFACE', '"xyz.openbmc_project.Inventory.Manager"')
configure_file(output : 'config.h',
configuration : conf_data)
diff --git a/nvme_config.json b/nvme_config.json
index 2f6423d..324ebd2 100644
--- a/nvme_config.json
+++ b/nvme_config.json
@@ -3,48 +3,80 @@
{
"NVMeDriveIndex": 0,
"NVMeDriveBusID": 16,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_0_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_0_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_0_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_0_locate",
"NVMeDrivePresentPin": 148,
"NVMeDrivePwrGoodPin": 161
},
{
"NVMeDriveIndex": 1,
"NVMeDriveBusID": 17,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_1_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_1_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_1_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_1_locate",
"NVMeDrivePresentPin": 149,
"NVMeDrivePwrGoodPin": 162
},
{
"NVMeDriveIndex": 2,
"NVMeDriveBusID": 18,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_2_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_2_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_2_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_2_locate",
"NVMeDrivePresentPin": 150,
"NVMeDrivePwrGoodPin": 163
},
{
"NVMeDriveIndex": 3,
"NVMeDriveBusID": 19,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_3_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_3_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_3_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_3_locate",
"NVMeDrivePresentPin": 151,
"NVMeDrivePwrGoodPin": 164
},
{
"NVMeDriveIndex": 4,
"NVMeDriveBusID": 20,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_4_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_4_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_4_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_4_locate",
"NVMeDrivePresentPin": 152,
"NVMeDrivePwrGoodPin": 165
},
{
"NVMeDriveIndex": 5,
"NVMeDriveBusID": 21,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_5_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_5_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_5_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_5_locate",
"NVMeDrivePresentPin": 153,
"NVMeDrivePwrGoodPin": 166
},
{
"NVMeDriveIndex": 6,
"NVMeDriveBusID": 22,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_6_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_6_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_6_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_6_locate",
"NVMeDrivePresentPin": 154,
"NVMeDrivePwrGoodPin": 167
},
{
"NVMeDriveIndex": 7,
"NVMeDriveBusID": 23,
+ "NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_7_fault",
+ "NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_7_locate",
+ "NVMeDriveLocateLEDControllerBusName": "xyz.openbmc_project.LED.Controller.led_u2_7_locate",
+ "NVMeDriveLocateLEDControllerPath": "/xyz/openbmc_project/led/physical/led_u2_7_locate",
"NVMeDrivePresentPin": 155,
"NVMeDrivePwrGoodPin": 168
}
diff --git a/nvme_manager.cpp b/nvme_manager.cpp
index 639f85d..0e0b7b7 100644
--- a/nvme_manager.cpp
+++ b/nvme_manager.cpp
@@ -7,8 +7,10 @@
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
+#include <sdbusplus/message.hpp>
#include <sstream>
#include <string>
+#include <xyz/openbmc_project/Led/Physical/server.hpp>
#include "i2c.h"
#define MONITOR_INTERVAL_SECONDS 1
@@ -16,6 +18,7 @@
#define GPIO_BASE_PATH "/sys/class/gpio/gpio"
#define IS_PRESENT "0"
#define POWERGD "1"
+#define NOWARNING_STRING "ff"
static constexpr auto configFile = "/etc/nvme/nvme_config.json";
static constexpr auto delay = std::chrono::milliseconds{100};
@@ -24,6 +27,13 @@
static constexpr const uint8_t COMMAND_CODE_0 = 0;
static constexpr const uint8_t COMMAND_CODE_8 = 8;
+static constexpr int CapacityFaultMask = 1;
+static constexpr int temperatureFaultMask = 1 << 1;
+static constexpr int DegradesFaultMask = 1 << 2;
+static constexpr int MediaFaultMask = 1 << 3;
+static constexpr int BackupDeviceFaultMask = 1 << 4;
+static constexpr int NOWARNING = 255;
+
static constexpr int SERIALNUMBER_START_INDEX = 3;
static constexpr int SERIALNUMBER_END_INDEX = 23;
@@ -39,6 +49,143 @@
using namespace std;
using namespace phosphor::logging;
+void Nvme::setNvmeInventoryProperties(
+ bool present, const phosphor::nvme::Nvme::NVMeData& nvmeData,
+ const std::string& inventoryPath)
+{
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ ITEM_IFACE, "Present", present);
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ ASSET_IFACE, "Manufacturer", nvmeData.vendor);
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ ASSET_IFACE, "SerialNumber",
+ nvmeData.serialNumber);
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "SmartWarnings",
+ nvmeData.smartWarnings);
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "StatusFlags",
+ nvmeData.statusFlags);
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "DriveLifeUsed",
+ nvmeData.driveLifeUsed);
+
+ auto smartWarning = (!nvmeData.smartWarnings.empty())
+ ? std::stoi(nvmeData.smartWarnings, 0, 16)
+ : NOWARNING;
+
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "CapacityFault",
+ !(smartWarning & CapacityFaultMask));
+
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "TemperatureFault",
+ !(smartWarning & temperatureFaultMask));
+
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "DegradesFault",
+ !(smartWarning & DegradesFaultMask));
+
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "MediaFault",
+ !(smartWarning & MediaFaultMask));
+
+ util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
+ NVME_STATUS_IFACE, "BackupDeviceFault",
+ !(smartWarning & BackupDeviceFaultMask));
+}
+
+void Nvme::setFaultLED(const std::string& locateLedGroupPath,
+ const std::string& faultLedGroupPath, bool request)
+{
+ if (locateLedGroupPath.empty() || faultLedGroupPath.empty())
+ {
+ return;
+ }
+
+ // Before toggle LED, check whether is Identify or not.
+ if (!getLEDGroupState(locateLedGroupPath))
+ {
+ util::SDBusPlus::setProperty(bus, LED_GROUP_BUSNAME, faultLedGroupPath,
+ LED_GROUP_IFACE, "Asserted", request);
+ }
+}
+
+void Nvme::setLocateLED(const std::string& locateLedGroupPath,
+ const std::string& locateLedBusName,
+ const std::string& locateLedPath, bool isPresent)
+{
+ if (locateLedGroupPath.empty() || locateLedBusName.empty() ||
+ locateLedPath.empty())
+ {
+ return;
+ }
+
+ namespace server = sdbusplus::xyz::openbmc_project::Led::server;
+
+ if (!getLEDGroupState(locateLedGroupPath))
+ {
+ if (isPresent)
+ util::SDBusPlus::setProperty(
+ bus, locateLedBusName, locateLedPath, LED_CONTROLLER_IFACE,
+ "State",
+ server::convertForMessage(server::Physical::Action::On));
+ else
+ util::SDBusPlus::setProperty(
+ bus, locateLedBusName, locateLedPath, LED_CONTROLLER_IFACE,
+ "State",
+ server::convertForMessage(server::Physical::Action::Off));
+ }
+}
+
+bool Nvme::getLEDGroupState(const std::string& ledPath)
+{
+ auto asserted = util::SDBusPlus::getProperty<bool>(
+ bus, LED_GROUP_BUSNAME, ledPath, LED_GROUP_IFACE, "Asserted");
+
+ return asserted;
+}
+
+void Nvme::setLEDsStatus(const phosphor::nvme::Nvme::NVMeConfig& config,
+ bool success,
+ const phosphor::nvme::Nvme::NVMeData& nvmeData)
+{
+ static std::unordered_map<std::string, bool> isError;
+
+ if (success)
+ {
+ if (!nvmeData.smartWarnings.empty())
+ {
+ auto request =
+ (strcmp(nvmeData.smartWarnings.c_str(), NOWARNING_STRING) == 0)
+ ? false
+ : true;
+
+ setFaultLED(config.locateLedGroupPath, config.faultLedGroupPath,
+ request);
+ setLocateLED(config.locateLedGroupPath,
+ config.locateLedControllerBusName,
+ config.locateLedControllerPath, !request);
+ }
+ isError[config.index] = false;
+ }
+ else
+ {
+ if (isError[config.index] != true)
+ {
+ // Drive is present but can not get data, turn on fault LED.
+ log<level::ERR>("Drive status is good but can not get data.",
+ entry("objPath = %s", config.index.c_str()));
+ isError[config.index] = true;
+ }
+
+ setFaultLED(config.locateLedGroupPath, config.faultLedGroupPath, true);
+ setLocateLED(config.locateLedGroupPath,
+ config.locateLedControllerBusName,
+ config.locateLedControllerPath, false);
+ }
+}
+
std::string intToHex(int input)
{
std::stringstream tmp;
@@ -141,6 +288,8 @@
void Nvme::run()
{
+ init();
+
std::function<void()> callback(std::bind(&Nvme::read, this));
try
{
@@ -215,13 +364,26 @@
{
uint8_t index = instance.value("NVMeDriveIndex", 0);
uint8_t busID = instance.value("NVMeDriveBusID", 0);
+ std::string faultLedGroupPath =
+ instance.value("NVMeDriveFaultLEDGroupPath", "");
+ std::string locateLedGroupPath =
+ instance.value("NVMeDriveLocateLEDGroupPath", "");
uint8_t presentPin = instance.value("NVMeDrivePresentPin", 0);
uint8_t pwrGoodPin = instance.value("NVMeDrivePwrGoodPin", 0);
+ std::string locateLedControllerBusName =
+ instance.value("NVMeDriveLocateLEDControllerBusName", "");
+ std::string locateLedControllerPath =
+ instance.value("NVMeDriveLocateLEDControllerPath", "");
nvmeConfig.index = std::to_string(index);
nvmeConfig.busID = busID;
+ nvmeConfig.faultLedGroupPath = faultLedGroupPath;
nvmeConfig.presentPin = presentPin;
nvmeConfig.pwrGoodPin = pwrGoodPin;
+ nvmeConfig.locateLedControllerBusName =
+ locateLedControllerBusName;
+ nvmeConfig.locateLedControllerPath = locateLedControllerPath;
+ nvmeConfig.locateLedGroupPath = locateLedGroupPath;
nvmeConfig.criticalHigh = criticalHigh;
nvmeConfig.criticalLow = criticalLow;
nvmeConfig.warningHigh = warningHigh;
@@ -275,11 +437,39 @@
return val;
}
+void Nvme::createNVMeInventory()
+{
+ using Properties =
+ std::map<std::string, sdbusplus::message::variant<std::string, bool>>;
+ using Interfaces = std::map<std::string, Properties>;
+
+ std::string inventoryPath;
+ std::map<sdbusplus::message::object_path, Interfaces> obj;
+
+ for (const auto config : configs)
+ {
+ inventoryPath = "/system/chassis/motherboard/nvme" + config.index;
+
+ obj = {{
+ inventoryPath,
+ {{ITEM_IFACE, {}}, {NVME_STATUS_IFACE, {}}, {ASSET_IFACE, {}}},
+ }};
+ util::SDBusPlus::CallMethod(bus, INVENTORY_BUSNAME, INVENTORY_NAMESPACE,
+ INVENTORY_MANAGER_IFACE, "Notify", obj);
+ }
+}
+
+void Nvme::init()
+{
+ createNVMeInventory();
+}
+
/** @brief Monitor NVMe drives every one second */
void Nvme::read()
{
std::string devPresentPath;
std::string devPwrGoodPath;
+ std::string inventoryPath;
static std::unordered_map<std::string, bool> isErrorPower;
@@ -292,6 +482,8 @@
devPwrGoodPath =
GPIO_BASE_PATH + std::to_string(config.pwrGoodPin) + "/value";
+ inventoryPath = NVME_INVENTORY_PATH + config.index;
+
auto iter = nvmes.find(config.index);
if (getGPIOValueOfNvme(devPresentPath) == IS_PRESENT)
@@ -301,7 +493,7 @@
if (getGPIOValueOfNvme(devPwrGoodPath) == POWERGD)
{
// get NVMe information through i2c by busID.
- getNVMeInfobyBusID(config.busID, nvmeData);
+ auto success = getNVMeInfobyBusID(config.busID, nvmeData);
// can not find. create dbus
if (iter == nvmes.end())
{
@@ -313,6 +505,7 @@
bus, objPath.c_str());
nvmes.emplace(config.index, nvmeSSD);
+ setNvmeInventoryProperties(true, nvmeData, inventoryPath);
nvmeSSD->setSensorValueToDbus(nvmeData.sensorValue);
nvmeSSD->setSensorThreshold(
config.criticalHigh, config.criticalLow,
@@ -320,19 +513,32 @@
config.warningLow);
nvmeSSD->checkSensorThreshold();
+ setLEDsStatus(config, success, nvmeData);
}
else
{
+ setNvmeInventoryProperties(true, nvmeData, inventoryPath);
iter->second->setSensorValueToDbus(nvmeData.sensorValue);
iter->second->checkSensorThreshold();
+ setLEDsStatus(config, success, nvmeData);
}
+
isErrorPower[config.index] = false;
}
else
{
// Present pin is true but power good pin is false
- // remove nvme d-bus path
+ // remove nvme d-bus path, clean all properties in inventory
+ // and turn on fault LED
+
+ setFaultLED(config.locateLedGroupPath, config.faultLedGroupPath,
+ true);
+ setLocateLED(config.locateLedGroupPath,
+ config.locateLedControllerBusName,
+ config.locateLedControllerPath, false);
+
nvmeData = NVMeData();
+ setNvmeInventoryProperties(false, nvmeData, inventoryPath);
nvmes.erase(config.index);
if (isErrorPower[config.index] != true)
@@ -349,8 +555,18 @@
}
else
{
- // Drive not present, remove nvme d-bus path
+ // Drive not present, remove nvme d-bus path ,
+ // clean all properties in inventory
+ // and turn off fault and locate LED
+
+ setFaultLED(config.locateLedGroupPath, config.faultLedGroupPath,
+ false);
+ setLocateLED(config.locateLedGroupPath,
+ config.locateLedControllerBusName,
+ config.locateLedControllerPath, false);
+
nvmeData = NVMeData();
+ setNvmeInventoryProperties(false, nvmeData, inventoryPath);
nvmes.erase(config.index);
}
}
diff --git a/nvme_manager.hpp b/nvme_manager.hpp
index 2b0e27d..85389e4 100644
--- a/nvme_manager.hpp
+++ b/nvme_manager.hpp
@@ -3,6 +3,7 @@
#include "config.h"
#include "nvmes.hpp"
+#include "sdbusplus.hpp"
#include <fstream>
#include <sdbusplus/bus.hpp>
@@ -32,7 +33,7 @@
/** @brief Constructs Nvme
*
* @param[in] bus - Handle to system dbus
- * @param[in] objPath - The Dbus path of nvme
+ * @param[in] objPath - The dbus path of nvme
*/
Nvme(sdbusplus::bus::bus& bus) :
bus(bus), _event(sdeventplus::Event::get_default()),
@@ -49,8 +50,12 @@
{
std::string index;
uint8_t busID;
+ std::string faultLedGroupPath;
uint8_t presentPin;
uint8_t pwrGoodPin;
+ std::string locateLedControllerBusName;
+ std::string locateLedControllerPath;
+ std::string locateLedGroupPath;
int8_t criticalHigh;
int8_t criticalLow;
int8_t maxValue;
@@ -87,6 +92,33 @@
std::unordered_map<std::string, std::shared_ptr<phosphor::nvme::NvmeSSD>>
nvmes;
+ /** @brief Set locate and fault LED status of SSD
+ *
+ * @param[in] config - Nvme configure data
+ * @param[in] success - Success or not that get NVMe Info by SMbus
+ * @param[in] nvmeData - Nvme information
+ */
+ void setLEDsStatus(const phosphor::nvme::Nvme::NVMeConfig& config,
+ bool success,
+ const phosphor::nvme::Nvme::NVMeData& nvmeData);
+
+ /** @brief Set SSD fault LED status */
+ void setFaultLED(const std::string& locateLedGroupPath,
+ const std::string& ledPath, bool request);
+ /** @brief Set SSD locate LED status */
+ void setLocateLED(const std::string& ledPath,
+ const std::string& locateLedBusName,
+ const std::string& locateLedPath, bool ispresent);
+ /** @brief Get Identify State*/
+ bool getLEDGroupState(const std::string& ledPath);
+
+ /** @brief Set inventory properties of nvme */
+ void setNvmeInventoryProperties(
+ bool present, const phosphor::nvme::Nvme::NVMeData& nvmeData,
+ const std::string& inventoryPath);
+
+ void createNVMeInventory();
+
private:
/** @brief sdbusplus bus client connection. */
sdbusplus::bus::bus& bus;
diff --git a/sdbusplus.hpp b/sdbusplus.hpp
new file mode 100644
index 0000000..9e26b3b
--- /dev/null
+++ b/sdbusplus.hpp
@@ -0,0 +1,104 @@
+#include <iostream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace nvme
+{
+namespace util
+{
+
+using namespace phosphor::logging;
+
+class SDBusPlus
+{
+ public:
+ template <typename T>
+ static auto
+ setProperty(sdbusplus::bus::bus& bus, const std::string& busName,
+ const std::string& objPath, const std::string& interface,
+ const std::string& property, const T& value)
+ {
+ sdbusplus::message::variant<T> data = value;
+
+ try
+ {
+ auto methodCall = bus.new_method_call(
+ busName.c_str(), objPath.c_str(), DBUS_PROPERTY_IFACE, "Set");
+
+ methodCall.append(interface.c_str());
+ methodCall.append(property);
+ methodCall.append(data);
+
+ auto reply = bus.call(methodCall);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Set properties fail.",
+ entry("ERROR = %s", e.what()),
+ entry("Object path = %s", objPath.c_str()));
+ return;
+ }
+ }
+
+ template <typename Property>
+ static auto
+ getProperty(sdbusplus::bus::bus& bus, const std::string& busName,
+ const std::string& objPath, const std::string& interface,
+ const std::string& property)
+ {
+ auto methodCall = bus.new_method_call(busName.c_str(), objPath.c_str(),
+ DBUS_PROPERTY_IFACE, "Get");
+
+ methodCall.append(interface.c_str());
+ methodCall.append(property);
+
+ sdbusplus::message::variant<Property> value;
+
+ try
+ {
+ auto reply = bus.call(methodCall);
+ reply.read(value);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Get properties fail.",
+ entry("ERROR = %s", e.what()),
+ entry("Object path = %s", objPath.c_str()));
+ return false;
+ }
+
+ return sdbusplus::message::variant_ns::get<Property>(value);
+ }
+
+ template <typename... Args>
+ static auto CallMethod(sdbusplus::bus::bus& bus, const std::string& busName,
+ const std::string& objPath,
+ const std::string& interface,
+ const std::string& method, Args&&... args)
+ {
+ auto reqMsg = bus.new_method_call(busName.c_str(), objPath.c_str(),
+ interface.c_str(), method.c_str());
+ reqMsg.append(std::forward<Args>(args)...);
+ try
+ {
+ auto respMsg = bus.call(reqMsg);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Call method fail.", entry("ERROR = %s", e.what()),
+ entry("Object path = %s", objPath.c_str()));
+ return;
+ }
+ }
+};
+
+} // namespace util
+} // namespace nvme
+} // namespace phosphor