Add the method to set Functional property based on Group state
When a particular LED Group asserted property is set to true, then the
functional state of that FRU is false and vice-versa. This commit adds
that behavior. Functional status is defined in
xyz.openbmc_project.State.Decorator.OperationalStatus interface.
Tested: When manually set the Asserted property to true by the D-Bus,
we can see that the Functional is updated to false.
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I6fa7a4c41363263d345b6b5335056fad15efb78c
diff --git a/group.cpp b/group.cpp
index 9292770..a6656d3 100644
--- a/group.cpp
+++ b/group.cpp
@@ -30,6 +30,11 @@
// Store asserted state
serialize.storeGroups(path, result);
+ // Set OperationalStatus according to the status of asserted property.
+ // If the group is asserted, then the functional status is false and
+ // vice-versa.
+ manager.setOperationalStatus(path, !value);
+
// If something does not go right here, then there should be an sdbusplus
// exception thrown.
manager.driveLEDs(ledsAssert, ledsDeAssert);
diff --git a/manager.cpp b/manager.cpp
index d19eeae..a1c4175 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -186,5 +186,57 @@
}
}
+// Set OperationalStatus functional according to the asserted state of the group
+void Manager::setOperationalStatus(const std::string& path, bool value) const
+{
+ using namespace phosphor::logging;
+
+ // Get endpoints from the rType
+ std::string fru = path + "/fru_fault";
+
+ // endpoint contains the vector of strings, where each string is a Inventory
+ // D-Bus object that this, associated with this LED Group D-Bus object
+ // pointed to by fru_fault
+ PropertyValue endpoint{};
+
+ try
+ {
+ endpoint = dBusHandler.getProperty(
+ fru, "xyz.openbmc_project.Association", "endpoints");
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ log<level::ERR>("Failed to get endpoints property",
+ entry("ERROR=%s", e.what()),
+ entry("PATH=%s", fru.c_str()));
+ return;
+ }
+
+ auto& endpoints = std::get<std::vector<std::string>>(endpoint);
+ if (endpoints.empty())
+ {
+ return;
+ }
+
+ for (const auto& fruInstancePath : endpoints)
+ {
+ // Set OperationalStatus by fru instance path
+ try
+ {
+ PropertyValue functionalValue{value};
+ dBusHandler.setProperty(
+ fruInstancePath,
+ "xyz.openbmc_project.State.Decorator.OperationalStatus",
+ "Functional", functionalValue);
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ log<level::ERR>("Failed to set Functional property",
+ entry("ERROR=%s", e.what()),
+ entry("PATH=%s", fruInstancePath.c_str()));
+ }
+ }
+}
+
} // namespace led
} // namespace phosphor
diff --git a/manager.hpp b/manager.hpp
index 390c8fe..91f8b53 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -105,6 +105,16 @@
*/
void driveLEDs(group& ledsAssert, group& ledsDeAssert);
+ /** @brief Set OperationalStatus according to the status of asserted
+ * property
+ *
+ * @param[in] path - D-Bus path of group
+ * @param[in] value - Could be true or false
+ *
+ * @return: None
+ */
+ void setOperationalStatus(const std::string& path, bool value) const;
+
private:
/** @brief sdbusplus handler */
sdbusplus::bus::bus& bus;
diff --git a/utils.cpp b/utils.cpp
index 136d20f..c9a21e5 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -47,6 +47,31 @@
return mapperResponse.cbegin()->first;
}
+// Get the property name
+const PropertyValue
+ DBusHandler::getProperty(const std::string& objectPath,
+ const std::string& interface,
+ const std::string& propertyName) const
+{
+ PropertyValue value{};
+
+ auto& bus = DBusHandler::getBus();
+ auto service = getService(objectPath, interface);
+ if (service.empty())
+ {
+ return value;
+ }
+
+ auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
+ DBUS_PROPERTY_IFACE, "Get");
+ method.append(interface, propertyName);
+
+ auto reply = bus.call(method);
+ reply.read(value);
+
+ return value;
+}
+
// Set property
void DBusHandler::setProperty(const std::string& objectPath,
const std::string& interface,
diff --git a/utils.hpp b/utils.hpp
index edb0315..68a616a 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -15,8 +15,10 @@
constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
// The value of the property(type: variant, contains some basic types)
-// Eg: uint8_t : dutyOn, uint16_t : Period, std::string : Name
-using PropertyValue = std::variant<uint8_t, uint16_t, std::string>;
+// Eg: uint8_t : dutyOn, uint16_t : Period, std::string : Name,
+// std::vector<std::string> : endpoints, bool : Functional
+using PropertyValue = std::variant<uint8_t, uint16_t, std::string,
+ std::vector<std::string>, bool>;
/**
* @class DBusHandler
@@ -47,6 +49,20 @@
const std::string getService(const std::string& path,
const std::string& interface) const;
+ /** @brief Get property(type: variant)
+ *
+ * @param[in] objectPath - D-Bus object path
+ * @param[in] interface - D-Bus interface
+ * @param[in] propertyName - D-Bus property name
+ *
+ * @return The value of the property(type: variant)
+ *
+ * @throw sdbusplus::exception::SdBusError when it fails
+ */
+ const PropertyValue getProperty(const std::string& objectPath,
+ const std::string& interface,
+ const std::string& propertyName) const;
+
/** @brief Set D-Bus property
*
* @param[in] objectPath - D-Bus object path