Drive physical LED when a LED group is actioned on
Change-Id: I3107c1d961c459379b77548a738533567eccf693
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/manager.cpp b/manager.cpp
index e4137d3..44b0480 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -1,6 +1,7 @@
#include <iostream>
#include <string>
#include <algorithm>
+#include <phosphor-logging/log.hpp>
#include "manager.hpp"
namespace phosphor
{
@@ -80,6 +81,13 @@
void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert,
group& ledsUpdate)
{
+ // For now, physical LED is driven by xyz.openbmc_project.Led.Controller
+ // at /xyz/openbmc_project/led/physical. However, its possible that in the
+ // future, the physical LEDs are driven by different dbus services.
+ // when that happens, service name needs to be obtained everytime a
+ // particular LED would be targeted as opposed to getting one now and then
+ // using it for all
+
// This order of LED operation is important.
if (ledsUpdate.size())
{
@@ -87,8 +95,8 @@
<< std::endl;
for (const auto& it: ledsUpdate)
{
- std::cout << "\t{" << it.name << "::" << it.action << "}"
- << std::endl;
+ std::string objPath = std::string(PHY_LED_PATH) + it.name;
+ drivePhysicalLED(objPath, it.action, it.dutyOn);
}
}
@@ -97,8 +105,8 @@
std::cout << "De-Asserting LEDs" << std::endl;
for (const auto& it: ledsDeAssert)
{
- std::cout << "\t{" << it.name << "::" << it.action << "}"
- << std::endl;
+ std::string objPath = std::string(PHY_LED_PATH) + it.name;
+ drivePhysicalLED(objPath, Layout::Action::Off, it.dutyOn);
}
}
@@ -107,12 +115,91 @@
std::cout << "Asserting LEDs" << std::endl;
for (const auto& it: ledsAssert)
{
- std::cout << "\t{" << it.name << "::" << it.action << "}"
- << std::endl;
+ std::string objPath = std::string(PHY_LED_PATH) + it.name;
+ drivePhysicalLED(objPath, it.action, it.dutyOn);
}
}
return;
}
+// Calls into driving physical LED post choosing the action
+void Manager::drivePhysicalLED(const std::string& objPath,
+ Layout::Action action,
+ uint8_t dutyOn)
+{
+ auto service = getServiceName(objPath, PHY_LED_IFACE);
+ if (!service.empty())
+ {
+ // If Blink, set its property
+ if (action == Layout::Action::Blink)
+ {
+ drivePhysicalLED(service, objPath, "DutyOn", dutyOn);
+ }
+ drivePhysicalLED(service, objPath, "State",
+ getPhysicalAction(action));
+ }
+}
+
+/** @brief Returns action string based on enum */
+const char* const Manager::getPhysicalAction(Layout::Action action)
+{
+ // TODO : When this is moved over to using libdus interfaces, this code will
+ // away. https://github.com/openbmc/phosphor-led-manager/issues/2
+ if(action == Layout::Action::On)
+ {
+ return "xyz.openbmc_project.Led.Physical.Action.On";
+ }
+ else if(action == Layout::Action::Blink)
+ {
+ return "xyz.openbmc_project.Led.Physical.Action.Blink";
+ }
+ else
+ {
+ return "xyz.openbmc_project.Led.Physical.Action.Off";
+ }
+}
+
+/** Given the LED dbus path and interface, returns the service name */
+std::string Manager::getServiceName(const std::string& objPath,
+ const std::string& interface) const
+{
+ using namespace phosphor::logging;
+
+ // Mapper dbus constructs
+ constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
+ constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/ObjectMapper";
+ constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
+
+ // Make a mapper call
+ auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
+ MAPPER_IFACE, "GetObject");
+ // Cook rest of the things.
+ mapperCall.append(objPath);
+ mapperCall.append(std::vector<std::string>({interface}));
+
+ auto reply = bus.call(mapperCall);
+ if (reply.is_method_error())
+ {
+ // Its okay if we do not see a corresponding physical LED.
+ log<level::INFO>("Error looking up Physical LED service",
+ entry("PATH=%s",objPath.c_str()));
+ return "";
+ }
+
+ // Response by mapper in the case of success
+ std::map<std::string, std::vector<std::string>> serviceNames;
+
+ // This is the service name for the passed in objpath
+ reply.read(serviceNames);
+ if (serviceNames.empty())
+ {
+ log<level::INFO>("Physical LED lookup did not return any service",
+ entry("PATH=%s",objPath.c_str()));
+ return "";
+ }
+
+ return serviceNames.begin()->first;
+}
+
} // namespace led
} // namespace phosphor